From git at videolan.org Sun Jun 1 11:47:40 2025 From: git at videolan.org (=?UTF-8?Q?Zhao_Zhili?=) Date: Sun, 01 Jun 2025 08:47:40 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?avcodec/h2645=5Fvui=3A_Ensure_color_pr?= =?utf-8?q?imaries/trc/space_isn=27t_reserved_value?= Message-ID: <20250601084741.4E8EB412CB7@natalya.videolan.org> ffmpeg | branch: master | Zhao Zhili | Thu May 22 13:06:15 2025 +0800| [c80002aa81e39f6bcc8d08c13acf8f9f61105cb0] | committer: Zhao Zhili avcodec/h2645_vui: Ensure color primaries/trc/space isn't reserved value Fix error reported by swscaler: Unsupported input (Operation not supported): fmt:yuv420p csp:unknown prim:reserved trc:bt709 -> fmt:yuv420p csp:bt709 prim:reserved trc:bt709 Signed-off-by: Zhao Zhili > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=c80002aa81e39f6bcc8d08c13acf8f9f61105cb0 --- libavcodec/h2645_vui.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libavcodec/h2645_vui.c b/libavcodec/h2645_vui.c index e5c7bf46f9..0e576c1563 100644 --- a/libavcodec/h2645_vui.c +++ b/libavcodec/h2645_vui.c @@ -67,11 +67,16 @@ void ff_h2645_decode_common_vui_params(GetBitContext *gb, H2645VUI *vui, void *l vui->matrix_coeffs = get_bits(gb, 8); // Set invalid values to "unspecified" - if (!av_color_primaries_name(vui->colour_primaries)) + if (vui->colour_primaries == AVCOL_PRI_RESERVED0 || + vui->colour_primaries == AVCOL_PRI_RESERVED || + !av_color_primaries_name(vui->colour_primaries)) vui->colour_primaries = AVCOL_PRI_UNSPECIFIED; - if (!av_color_transfer_name(vui->transfer_characteristics)) + if (vui->transfer_characteristics == AVCOL_TRC_RESERVED0 || + vui->transfer_characteristics == AVCOL_TRC_RESERVED || + !av_color_transfer_name(vui->transfer_characteristics)) vui->transfer_characteristics = AVCOL_TRC_UNSPECIFIED; - if (!av_color_space_name(vui->matrix_coeffs)) + if (vui->matrix_coeffs == AVCOL_SPC_RESERVED || + !av_color_space_name(vui->matrix_coeffs)) vui->matrix_coeffs = AVCOL_SPC_UNSPECIFIED; } } From git at videolan.org Sun Jun 1 11:47:42 2025 From: git at videolan.org (=?UTF-8?Q?Zhao_Zhili?=) Date: Sun, 01 Jun 2025 08:47:42 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?tests/fate/cbs=3A_Add_hevc_metadata_se?= =?utf-8?q?t_color_test?= Message-ID: <20250601084743.56A08412CBA@natalya.videolan.org> ffmpeg | branch: master | Zhao Zhili | Thu May 22 13:06:36 2025 +0800| [9a19ba40678220c1ac8ec00501fb1372ced2e826] | committer: Zhao Zhili tests/fate/cbs: Add hevc metadata set color test Signed-off-by: Zhao Zhili > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9a19ba40678220c1ac8ec00501fb1372ced2e826 --- tests/fate/cbs.mak | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/fate/cbs.mak b/tests/fate/cbs.mak index 32207e2ee2..138dab67a9 100644 --- a/tests/fate/cbs.mak +++ b/tests/fate/cbs.mak @@ -172,6 +172,11 @@ $(foreach N,$(FATE_CBS_DISCARD_TYPES),$(eval $(call FATE_CBS_DISCARD_TEST,hevc,$ FATE_CBS_HEVC-$(call ALLYES, HEVC_DEMUXER HEVC_MUXER HEVC_PARSER FILTER_UNITS_BSF HEVC_METADATA_BSF FILE_PROTOCOL) += $(FATE_CBS_hevc_DISCARD) +fate-cbs-hevc-metadata-set-color: CMD = md5 -i $(TARGET_SAMPLES)/hevc-conformance/AMP_A_Samsung_4.bit -c:v copy -bsf:v hevc_metadata=colour_primaries=0:transfer_characteristics=0:matrix_coefficients=3 -f hevc +fate-cbs-hevc-metadata-set-color: CMP = oneline +fate-cbs-hevc-metadata-set-color: REF = d073124fca9e30a46c173292f948967c +FATE_CBS_HEVC-$(call ALLYES, HEVC_DEMUXER, HEVC_METADATA_BSF, HEVC_MUXER) += fate-cbs-hevc-metadata-set-color + FATE_SAMPLES_AVCONV += $(FATE_CBS_HEVC-yes) fate-cbs-hevc: $(FATE_CBS_HEVC-yes) From git at videolan.org Sun Jun 1 11:47:44 2025 From: git at videolan.org (=?UTF-8?Q?Zhao_Zhili?=) Date: Sun, 01 Jun 2025 08:47:44 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?tests/fate/hevc=3A_Fix_dependancy_for_?= =?utf-8?q?hevc-alpha?= Message-ID: <20250601084745.627DB412CBB@natalya.videolan.org> ffmpeg | branch: master | Zhao Zhili | Thu May 22 13:06:57 2025 +0800| [64116800bef4e1a7960a2ac0aecd6f3b9e3e6add] | committer: Zhao Zhili tests/fate/hevc: Fix dependancy for hevc-alpha Signed-off-by: Zhao Zhili > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=64116800bef4e1a7960a2ac0aecd6f3b9e3e6add --- tests/fate/hevc.mak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak index e432345ef7..390ccf46e2 100644 --- a/tests/fate/hevc.mak +++ b/tests/fate/hevc.mak @@ -292,7 +292,7 @@ fate-hevc-mv-position: CMD = framecrc -i $(TARGET_SAMPLES)/hevc/multiview.mov -m FATE_HEVC-$(call FRAMECRC, MOV, HEVC) += fate-hevc-mv-position fate-hevc-alpha: CMD = framecrc -i $(TARGET_SAMPLES)/hevc/alpha.mp4 -FATE_HEVC-$(call FRAMECRC, HEVC, HEVC) += fate-hevc-alpha +FATE_HEVC-$(call FRAMECRC, MOV, HEVC) += fate-hevc-alpha FATE_SAMPLES_AVCONV += $(FATE_HEVC-yes) FATE_SAMPLES_FFPROBE += $(FATE_HEVC_FFPROBE-yes) From git at videolan.org Sun Jun 1 11:47:46 2025 From: git at videolan.org (=?UTF-8?Q?Zhao_Zhili?=) Date: Sun, 01 Jun 2025 08:47:46 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?tests=3A_Add_fate-hevc-color-reserved?= Message-ID: <20250601084747.6F61A412CB7@natalya.videolan.org> ffmpeg | branch: master | Zhao Zhili | Thu May 22 13:07:17 2025 +0800| [3d9b284ad148ac4ccad21773f7ae44ab80a3da6d] | committer: Zhao Zhili tests: Add fate-hevc-color-reserved Signed-off-by: Zhao Zhili > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=3d9b284ad148ac4ccad21773f7ae44ab80a3da6d --- tests/fate/hevc.mak | 3 +++ tests/ref/fate/hevc-color-reserved | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak index 390ccf46e2..8113c04300 100644 --- a/tests/fate/hevc.mak +++ b/tests/fate/hevc.mak @@ -294,6 +294,9 @@ FATE_HEVC-$(call FRAMECRC, MOV, HEVC) += fate-hevc-mv-position fate-hevc-alpha: CMD = framecrc -i $(TARGET_SAMPLES)/hevc/alpha.mp4 FATE_HEVC-$(call FRAMECRC, MOV, HEVC) += fate-hevc-alpha +fate-hevc-color-reserved: CMD = framecrc -bsf:v hevc_metadata=colour_primaries=0:transfer_characteristics=0:matrix_coefficients=3 -i $(TARGET_SAMPLES)/hevc-conformance/AMP_A_Samsung_4.bit -vf scale,format=nv12 -frames:v 1 +FATE_HEVC-$(call FRAMECRC, HEVC, HEVC, HEVC_METADATA_BSF SCALE_FILTER) += fate-hevc-color-reserved + FATE_SAMPLES_AVCONV += $(FATE_HEVC-yes) FATE_SAMPLES_FFPROBE += $(FATE_HEVC_FFPROBE-yes) diff --git a/tests/ref/fate/hevc-color-reserved b/tests/ref/fate/hevc-color-reserved new file mode 100644 index 0000000000..cba6397aa8 --- /dev/null +++ b/tests/ref/fate/hevc-color-reserved @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 2560x1600 +#sar 0: 0/1 +0, 0, 0, 1, 6144000, 0x427b9a00 From git at videolan.org Sun Jun 1 11:47:48 2025 From: git at videolan.org (=?UTF-8?Q?Zhao_Zhili?=) Date: Sun, 01 Jun 2025 08:47:48 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?avformat/movenc=3A_Fix_flush_fragment?= Message-ID: <20250601084749.7F883412CBE@natalya.videolan.org> ffmpeg | branch: master | Zhao Zhili | Thu May 22 17:37:05 2025 +0800| [56cf1c084d50e1b8bb2e667bb9c0aaecb4ae48fc] | committer: Zhao Zhili avformat/movenc: Fix flush fragment The follow cmd output corrupted file before the patch: ffmpeg -f lavfi -i color=blue,trim=duration=0.04 \ -f lavfi -i anullsrc,atrim=duration=2 \ -movflags +empty_moov+hybrid_fragmented \ -frag_duration 1000000 \ -frag_interleave 1 \ output.mp4 1. first_track is the first track with track->entry != 0. As in the command above, video track (track index 0) has a single frame. When flush the second fragment, first_track is 1, the audio track. 2. write_moof = i == first_track, so write_moof is false for i = 0. 3. When mov->frag_interleave != 0, mov->mdat_buf != NULL, because it contains audio data. So avio_write is called before write_moof, that is, the data write before moof, and mov_finish_fragment executed with wrong mdat_start. 4. With normal fmp4 output, the error isn't obvious. With hybrid_fragmented, ffplay output.mp4 shows a lot of error messages. Signed-off-by: Zhao Zhili > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=56cf1c084d50e1b8bb2e667bb9c0aaecb4ae48fc --- libavformat/movenc.c | 4 ++-- tests/fate/mov.mak | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index f11633525e..246fc2912c 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -6509,9 +6509,9 @@ static int mov_flush_fragment(AVFormatContext *s, int force) int buf_size, write_moof = 1, moof_tracks = -1; uint8_t *buf; + if (!track->entry) + continue; if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) { - if (!track->entry) - continue; mdat_size = avio_tell(track->mdat_buf); moof_tracks = i; } else { diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak index f7e5e52217..6ab61e9f00 100644 --- a/tests/fate/mov.mak +++ b/tests/fate/mov.mak @@ -84,6 +84,11 @@ fate-mov-ibi-elst-starts-b: CMD = framemd5 -flags +bitexact -i $(TARGET_SAMPLES) # Makes sure that we handle overlapping framgments fate-mov-frag-overlap: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/frag_overlap.mp4 +fate-mov-mp4-frag-flush: CMD = md5 -f lavfi -i color=blue,format=rgb24,trim=duration=0.04 -f lavfi -i anullsrc,aformat=s16,atrim=duration=2 -c:v png -c:a pcm_s16le -movflags +empty_moov+hybrid_fragmented -frag_duration 1000000 -frag_interleave 1 -f mp4 +fate-mov-mp4-frag-flush: CMP = oneline +fate-mov-mp4-frag-flush: REF = a10c0e2e2dfc120f31ca5e59e0e4392a +FATE_MOV-$(call ALLYES, LAVFI_INDEV, COLOR_FILTER, FORMAT_FILTER, TRIM_FILTER, ANULL_FILTER, AFORMAT_FILTER, ATRIM_FILTER, PNG_ENCODER, PCM_S16LE_ENCODER, MOV_MUXER) += fate-mov-mp4-frag-flush + # Makes sure that we pick the right frames according to edit list when there is no keyframe with PTS < edit list start. # For example, when video starts on a B-frame, and edit list starts on that B-frame too. # GOP structure : B B I in presentation order. From git at videolan.org Sun Jun 1 11:47:50 2025 From: git at videolan.org (=?UTF-8?Q?Zhao_Zhili?=) Date: Sun, 01 Jun 2025 08:47:50 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?avformat/movenc=3A_Reduce_loop_iterati?= =?utf-8?q?ons_in_mov=5Fflush=5Ffragment?= Message-ID: <20250601084751.8C186412CBA@natalya.videolan.org> ffmpeg | branch: master | Zhao Zhili | Fri May 23 12:01:08 2025 +0800| [8ea2b993fdd15395a5bf6e0edbdca850d4553da9] | committer: Zhao Zhili avformat/movenc: Reduce loop iterations in mov_flush_fragment Signed-off-by: Zhao Zhili > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8ea2b993fdd15395a5bf6e0edbdca850d4553da9 --- libavformat/movenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 246fc2912c..402611e81e 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -6504,7 +6504,7 @@ static int mov_flush_fragment(AVFormatContext *s, int force) av_rescale(mov->tracks[first_track].cluster[0].dts, AV_TIME_BASE, mov->tracks[first_track].timescale), (has_video ? starts_with_key : mov->tracks[first_track].cluster[0].flags & MOV_SYNC_SAMPLE) ? AVIO_DATA_MARKER_SYNC_POINT : AVIO_DATA_MARKER_BOUNDARY_POINT); - for (i = 0; i < mov->nb_tracks; i++) { + for (i = first_track; i < mov->nb_tracks; i++) { MOVTrack *track = &mov->tracks[i]; int buf_size, write_moof = 1, moof_tracks = -1; uint8_t *buf; From git at videolan.org Sun Jun 1 20:32:21 2025 From: git at videolan.org (=?UTF-8?Q?James_Almer?=) Date: Sun, 01 Jun 2025 17:32:21 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?fftools/ffmpeg=5Ffilter=3A_make_Filter?= =?utf-8?q?GraphPriv_private_again?= Message-ID: <20250601173222.DB4A9412B83@natalya.videolan.org> ffmpeg | branch: master | James Almer | Tue May 27 23:58:09 2025 -0300| [1f034714f6e8855ff217c176168df4b64c313b63] | committer: James Almer fftools/ffmpeg_filter: make FilterGraphPriv private again As the name implies, it's a struct meant to be internal and private to the filter handling code. If a field is required in other modules, then it can be moved to the public facing struct, which is done in this commit. Signed-off-by: James Almer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1f034714f6e8855ff217c176168df4b64c313b63 --- fftools/ffmpeg.h | 4 ++++ fftools/ffmpeg_filter.c | 51 ++++++++++++++++++++++++++++++++++++++-------- fftools/ffmpeg_filter.h | 42 -------------------------------------- fftools/graph/graphprint.c | 16 ++++++--------- 4 files changed, 53 insertions(+), 60 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 7fbf0ad532..641582ae63 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -39,6 +39,7 @@ #include "libavfilter/avfilter.h" #include "libavutil/avutil.h" +#include "libavutil/bprint.h" #include "libavutil/dict.h" #include "libavutil/eval.h" #include "libavutil/fifo.h" @@ -381,6 +382,9 @@ typedef struct FilterGraph { int nb_inputs; OutputFilter **outputs; int nb_outputs; + + const char *graph_desc; + struct AVBPrint graph_print_buf; } FilterGraph; enum DecoderFlags { diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index b774606562..464e17ca7c 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -44,6 +44,42 @@ // FIXME private header, used for mid_pred() #include "libavcodec/mathops.h" +typedef struct FilterGraphPriv { + FilterGraph fg; + + // name used for logging + char log_name[32]; + + int is_simple; + // true when the filtergraph contains only meta filters + // that do not modify the frame data + int is_meta; + // source filters are present in the graph + int have_sources; + int disable_conversions; + + unsigned nb_outputs_done; + + int nb_threads; + + // frame for temporarily holding output from the filtergraph + AVFrame *frame; + // frame for sending output to the encoder + AVFrame *frame_enc; + + Scheduler *sch; + unsigned sch_idx; +} FilterGraphPriv; + +static FilterGraphPriv *fgp_from_fg(FilterGraph *fg) +{ + return (FilterGraphPriv*)fg; +} + +static const FilterGraphPriv *cfgp_from_cfg(const FilterGraph *fg) +{ + return (const FilterGraphPriv*)fg; +} // data that is local to the filter thread and not visible outside of it typedef struct FilterGraphThread { @@ -856,7 +892,7 @@ void fg_free(FilterGraph **pfg) av_freep(&fg->outputs[j]); } av_freep(&fg->outputs); - av_freep(&fgp->graph_desc); + av_freep(&fg->graph_desc); av_frame_free(&fgp->frame); av_frame_free(&fgp->frame_enc); @@ -909,7 +945,7 @@ int fg_create(FilterGraph **pfg, char *graph_desc, Scheduler *sch) } fg->class = &fg_class; - fgp->graph_desc = graph_desc; + fg->graph_desc = graph_desc; fgp->disable_conversions = !auto_conversion_filters; fgp->nb_threads = -1; fgp->sch = sch; @@ -928,7 +964,7 @@ int fg_create(FilterGraph **pfg, char *graph_desc, Scheduler *sch) return AVERROR(ENOMEM);; graph->nb_threads = 1; - ret = graph_parse(fg, graph, fgp->graph_desc, &inputs, &outputs, + ret = graph_parse(fg, graph, fg->graph_desc, &inputs, &outputs, hw_device_for_filter()); if (ret < 0) goto fail; @@ -1070,7 +1106,6 @@ int fg_create_simple(FilterGraph **pfg, static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter) { - FilterGraphPriv *fgp = fgp_from_fg(fg); InputFilterPriv *ifp = ifp_from_ifilter(ifilter); InputStream *ist = NULL; enum AVMediaType type = ifp->type; @@ -1086,7 +1121,7 @@ static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter) dec_idx = strtol(ifp->linklabel + 4, &p, 0); if (dec_idx < 0 || dec_idx >= nb_decoders) { av_log(fg, AV_LOG_ERROR, "Invalid decoder index %d in filtergraph description %s\n", - dec_idx, fgp->graph_desc); + dec_idx, fg->graph_desc); return AVERROR(EINVAL); } @@ -1137,7 +1172,7 @@ static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter) file_idx = strtol(ifp->linklabel, &p, 0); if (file_idx < 0 || file_idx >= nb_input_files) { av_log(fg, AV_LOG_FATAL, "Invalid file index %d in filtergraph description %s.\n", - file_idx, fgp->graph_desc); + file_idx, fg->graph_desc); return AVERROR(EINVAL); } s = input_files[file_idx]->ctx; @@ -1171,7 +1206,7 @@ static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter) stream_specifier_uninit(&ss); if (!st) { av_log(fg, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s " - "matches no streams.\n", p, fgp->graph_desc); + "matches no streams.\n", p, fg->graph_desc); return AVERROR(EINVAL); } ist = input_files[file_idx]->streams[st->index]; @@ -1733,7 +1768,7 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt) AVFilterInOut *inputs, *outputs, *cur; int ret = AVERROR_BUG, i, simple = filtergraph_is_simple(fg); int have_input_eof = 0; - const char *graph_desc = fgp->graph_desc; + const char *graph_desc = fg->graph_desc; cleanup_filtergraph(fg, fgt); fgt->graph = avfilter_graph_alloc(); diff --git a/fftools/ffmpeg_filter.h b/fftools/ffmpeg_filter.h index 94b94beece..bf690bdc91 100644 --- a/fftools/ffmpeg_filter.h +++ b/fftools/ffmpeg_filter.h @@ -37,48 +37,6 @@ #include "libavutil/channel_layout.h" #include "libavutil/downmix_info.h" -typedef struct FilterGraphPriv { - FilterGraph fg; - - // name used for logging - char log_name[32]; - - int is_simple; - // true when the filtergraph contains only meta filters - // that do not modify the frame data - int is_meta; - // source filters are present in the graph - int have_sources; - int disable_conversions; - - unsigned nb_outputs_done; - - const char *graph_desc; - - int nb_threads; - - // frame for temporarily holding output from the filtergraph - AVFrame *frame; - // frame for sending output to the encoder - AVFrame *frame_enc; - - Scheduler *sch; - unsigned sch_idx; - - AVBPrint graph_print_buf; - -} FilterGraphPriv; - -static inline FilterGraphPriv *fgp_from_fg(FilterGraph *fg) -{ - return (FilterGraphPriv*)fg; -} - -static inline const FilterGraphPriv *cfgp_from_cfg(const FilterGraph *fg) -{ - return (const FilterGraphPriv*)fg; -} - typedef struct InputFilterPriv { InputFilter ifilter; diff --git a/fftools/graph/graphprint.c b/fftools/graph/graphprint.c index 852a8f6c0c..e55c8d7507 100644 --- a/fftools/graph/graphprint.c +++ b/fftools/graph/graphprint.c @@ -479,14 +479,13 @@ static void init_sections(void) static void print_filtergraph_single(GraphPrintContext *gpc, FilterGraph *fg, AVFilterGraph *graph) { AVTextFormatContext *tfc = gpc->tfc; - FilterGraphPriv *fgp = fgp_from_fg(fg); AVDictionary *input_map = NULL; AVDictionary *output_map = NULL; print_int("graph_index", fg->index); print_fmt("name", "Graph %d.%d", gpc->id_prefix_num, fg->index); print_fmt("id", "Graph_%d_%d", gpc->id_prefix_num, fg->index); - print_str("description", fgp->graph_desc); + print_str("description", fg->graph_desc); print_section_header_id(gpc, SECTION_ID_GRAPH_INPUTS, "Input_File", 0); @@ -557,7 +556,7 @@ static void print_filtergraph_single(GraphPrintContext *gpc, FilterGraph *fg, AV if (gpc->is_diagram) { print_fmt("name", "Graph %d.%d", gpc->id_prefix_num, fg->index); - print_str("description", fgp->graph_desc); + print_str("description", fg->graph_desc); print_str("id", sec_ctx.context_id); } @@ -967,11 +966,10 @@ int print_filtergraph(FilterGraph *fg, AVFilterGraph *graph) { GraphPrintContext *gpc = NULL; AVTextFormatContext *tfc; - FilterGraphPriv *fgp = fgp_from_fg(fg); - AVBPrint *target_buf = &fgp->graph_print_buf; + AVBPrint *target_buf = &fg->graph_print_buf; int ret; - if (!fg || !fgp) { + if (!fg) { av_log(NULL, AV_LOG_ERROR, "Invalid filter graph provided\n"); return AVERROR(EINVAL); } @@ -1035,8 +1033,7 @@ static int print_filtergraphs_priv(FilterGraph **graphs, int nb_graphs, InputFil avtext_print_section_header(tfc, NULL, SECTION_ID_FILTERGRAPHS); for (int i = 0; i < nb_graphs; i++) { - FilterGraphPriv *fgp = fgp_from_fg(graphs[i]); - AVBPrint *graph_buf = &fgp->graph_print_buf; + AVBPrint *graph_buf = &graphs[i]->graph_print_buf; if (graph_buf->len > 0) { avtext_print_section_header(tfc, NULL, SECTION_ID_FILTERGRAPH); @@ -1053,8 +1050,7 @@ static int print_filtergraphs_priv(FilterGraph **graphs, int nb_graphs, InputFil OutputStream *ost = of->streams[i]; if (ost->fg_simple) { - FilterGraphPriv *fgp = fgp_from_fg(ost->fg_simple); - AVBPrint *graph_buf = &fgp->graph_print_buf; + AVBPrint *graph_buf = &ost->fg_simple->graph_print_buf; if (graph_buf->len > 0) { avtext_print_section_header(tfc, NULL, SECTION_ID_FILTERGRAPH); From git at videolan.org Sun Jun 1 20:32:23 2025 From: git at videolan.org (=?UTF-8?Q?James_Almer?=) Date: Sun, 01 Jun 2025 17:32:23 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?fftools/ffmpeg=5Ffilter=3A_make_InputF?= =?utf-8?q?ilterPriv_and_OutputFilterPriv_private_again?= Message-ID: <20250601173224.ECA64412B87@natalya.videolan.org> ffmpeg | branch: master | James Almer | Wed May 28 20:12:58 2025 -0300| [6ede1e3fbfa0aae09076529ace1aa7d114d65f5f] | committer: James Almer fftools/ffmpeg_filter: make InputFilterPriv and OutputFilterPriv private again As the names imply, they are structs meant to be internal and private to the filter handling code. If a field is required in other modules, then it can be moved to the public facing structs, which is done in this commit. Signed-off-by: James Almer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=6ede1e3fbfa0aae09076529ace1aa7d114d65f5f --- fftools/ffmpeg.h | 17 +++ fftools/ffmpeg_filter.c | 319 ++++++++++++++++++++++++++++++++------------- fftools/ffmpeg_filter.h | 192 --------------------------- fftools/graph/graphprint.c | 18 +-- fftools/resources/resman.c | 1 - 5 files changed, 256 insertions(+), 291 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 641582ae63..7868f3d85f 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -353,6 +353,18 @@ typedef struct OutputFilterOptions { typedef struct InputFilter { struct FilterGraph *graph; uint8_t *name; + int index; + + // filter data type + enum AVMediaType type; + + AVFilterContext *filter; + + char *input_name; + + /* for filters that are not yet bound to an input stream, + * this stores the input linklabel, if any */ + uint8_t *linklabel; } InputFilter; typedef struct OutputFilter { @@ -360,6 +372,11 @@ typedef struct OutputFilter { struct FilterGraph *graph; uint8_t *name; + int index; + + AVFilterContext *filter; + + char *output_name; /* for filters that are not yet bound to an output stream, * this stores the output linklabel, if any */ diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 464e17ca7c..e0c40ffe00 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -21,7 +21,6 @@ #include #include "ffmpeg.h" -#include "ffmpeg_filter.h" #include "graph/graphprint.h" #include "libavfilter/avfilter.h" @@ -102,6 +101,141 @@ typedef struct FilterGraphThread { uint8_t *eof_out; } FilterGraphThread; +typedef struct InputFilterPriv { + InputFilter ifilter; + + InputFilterOptions opts; + + // used to hold submitted input + AVFrame *frame; + + // source data type: AVMEDIA_TYPE_SUBTITLE for sub2video, + // same as type otherwise + enum AVMediaType type_src; + + int eof; + int bound; + int drop_warned; + uint64_t nb_dropped; + + // parameters configured for this input + int format; + + int width, height; + AVRational sample_aspect_ratio; + enum AVColorSpace color_space; + enum AVColorRange color_range; + + int sample_rate; + AVChannelLayout ch_layout; + + AVRational time_base; + + AVFrameSideData **side_data; + int nb_side_data; + + AVFifo *frame_queue; + + AVBufferRef *hw_frames_ctx; + + int displaymatrix_present; + int displaymatrix_applied; + int32_t displaymatrix[9]; + + int downmixinfo_present; + AVDownmixInfo downmixinfo; + + struct { + AVFrame *frame; + + int64_t last_pts; + int64_t end_pts; + + /// marks if sub2video_update should force an initialization + unsigned int initialize; + } sub2video; +} InputFilterPriv; + +static InputFilterPriv *ifp_from_ifilter(InputFilter *ifilter) +{ + return (InputFilterPriv*)ifilter; +} + +typedef struct FPSConvContext { + AVFrame *last_frame; + /* number of frames emitted by the video-encoding sync code */ + int64_t frame_number; + /* history of nb_frames_prev, i.e. the number of times the + * previous frame was duplicated by vsync code in recent + * do_video_out() calls */ + int64_t frames_prev_hist[3]; + + uint64_t dup_warning; + + int last_dropped; + int dropped_keyframe; + + enum VideoSyncMethod vsync_method; + + AVRational framerate; + AVRational framerate_max; + const AVRational *framerate_supported; + int framerate_clip; +} FPSConvContext; + +typedef struct OutputFilterPriv { + OutputFilter ofilter; + + void *log_parent; + char log_name[32]; + + /* desired output stream properties */ + int format; + int width, height; + int sample_rate; + AVChannelLayout ch_layout; + enum AVColorSpace color_space; + enum AVColorRange color_range; + + AVFrameSideData **side_data; + int nb_side_data; + + // time base in which the output is sent to our downstream + // does not need to match the filtersink's timebase + AVRational tb_out; + // at least one frame with the above timebase was sent + // to our downstream, so it cannot change anymore + int tb_out_locked; + + AVRational sample_aspect_ratio; + + AVDictionary *sws_opts; + AVDictionary *swr_opts; + + // those are only set if no format is specified and the encoder gives us multiple options + // They point directly to the relevant lists of the encoder. + const int *formats; + const AVChannelLayout *ch_layouts; + const int *sample_rates; + const enum AVColorSpace *color_spaces; + const enum AVColorRange *color_ranges; + + AVRational enc_timebase; + int64_t trim_start_us; + int64_t trim_duration_us; + // offset for output timestamps, in AV_TIME_BASE_Q + int64_t ts_offset; + int64_t next_pts; + FPSConvContext fps; + + unsigned flags; +} OutputFilterPriv; + +static OutputFilterPriv *ofp_from_ofilter(OutputFilter *ofilter) +{ + return (OutputFilterPriv*)ofilter; +} + typedef struct FilterCommand { char *target; char *command; @@ -182,7 +316,7 @@ static void sub2video_push_ref(InputFilterPriv *ifp, int64_t pts) av_assert1(frame->data[0]); ifp->sub2video.last_pts = frame->pts = pts; - ret = av_buffersrc_add_frame_flags(ifp->filter, frame, + ret = av_buffersrc_add_frame_flags(ifp->ifilter.filter, frame, AV_BUFFERSRC_FLAG_KEEP_REF | AV_BUFFERSRC_FLAG_PUSH); if (ret != AVERROR_EOF && ret < 0) @@ -516,10 +650,10 @@ static OutputFilter *ofilter_alloc(FilterGraph *fg, enum AVMediaType type) ofp->format = -1; ofp->color_space = AVCOL_SPC_UNSPECIFIED; ofp->color_range = AVCOL_RANGE_UNSPECIFIED; - ofp->index = fg->nb_outputs - 1; + ofilter->index = fg->nb_outputs - 1; snprintf(ofp->log_name, sizeof(ofp->log_name), "%co%d", - av_get_media_type_string(type)[0], ofp->index); + av_get_media_type_string(type)[0], ofilter->index); return ofilter; } @@ -535,10 +669,10 @@ static int ifilter_bind_ist(InputFilter *ifilter, InputStream *ist, av_assert0(!ifp->bound); ifp->bound = 1; - if (ifp->type != ist->par->codec_type && - !(ifp->type == AVMEDIA_TYPE_VIDEO && ist->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) { + if (ifilter->type != ist->par->codec_type && + !(ifilter->type == AVMEDIA_TYPE_VIDEO && ist->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) { av_log(fgp, AV_LOG_ERROR, "Tried to connect %s stream to %s filtergraph input\n", - av_get_media_type_string(ist->par->codec_type), av_get_media_type_string(ifp->type)); + av_get_media_type_string(ist->par->codec_type), av_get_media_type_string(ifilter->type)); return AVERROR(EINVAL); } @@ -553,8 +687,12 @@ static int ifilter_bind_ist(InputFilter *ifilter, InputStream *ist, if (ret < 0) return ret; + ifilter->input_name = av_strdup(ifp->opts.name); + if (!ifilter->input_name) + return AVERROR(EINVAL); + ret = sch_connect(fgp->sch, - src, SCH_FILTER_IN(fgp->sch_idx, ifp->index)); + src, SCH_FILTER_IN(fgp->sch_idx, ifilter->index)); if (ret < 0) return ret; @@ -589,19 +727,23 @@ static int ifilter_bind_dec(InputFilterPriv *ifp, Decoder *dec, av_assert0(!ifp->bound); ifp->bound = 1; - if (ifp->type != dec->type) { + if (ifp->ifilter.type != dec->type) { av_log(fgp, AV_LOG_ERROR, "Tried to connect %s decoder to %s filtergraph input\n", - av_get_media_type_string(dec->type), av_get_media_type_string(ifp->type)); + av_get_media_type_string(dec->type), av_get_media_type_string(ifp->ifilter.type)); return AVERROR(EINVAL); } - ifp->type_src = ifp->type; + ifp->type_src = ifp->ifilter.type; ret = dec_filter_add(dec, &ifp->ifilter, &ifp->opts, vs, &src); if (ret < 0) return ret; - ret = sch_connect(fgp->sch, src, SCH_FILTER_IN(fgp->sch_idx, ifp->index)); + ifp->ifilter.input_name = av_strdup(ifp->opts.name); + if (!ifp->ifilter.input_name) + return AVERROR(EINVAL); + + ret = sch_connect(fgp->sch, src, SCH_FILTER_IN(fgp->sch_idx, ifp->ifilter.index)); if (ret < 0) return ret; @@ -670,8 +812,8 @@ int ofilter_bind_enc(OutputFilter *ofilter, unsigned sched_idx_enc, ofp->trim_start_us = opts->trim_start_us; ofp->trim_duration_us = opts->trim_duration_us; - ofp->name = av_strdup(opts->name); - if (!ofp->name) + ofilter->output_name = av_strdup(opts->name); + if (!ofilter->output_name) return AVERROR(EINVAL); ret = av_dict_copy(&ofp->sws_opts, opts->sws_opts, 0); @@ -691,7 +833,7 @@ int ofilter_bind_enc(OutputFilter *ofilter, unsigned sched_idx_enc, ofp->log_parent = NULL; av_strlcpy(ofp->log_name, fgp->log_name, sizeof(ofp->log_name)); } else - av_strlcatf(ofp->log_name, sizeof(ofp->log_name), "->%s", ofp->name); + av_strlcatf(ofp->log_name, sizeof(ofp->log_name), "->%s", ofilter->output_name); switch (ofilter->type) { case AVMEDIA_TYPE_VIDEO: @@ -750,7 +892,7 @@ int ofilter_bind_enc(OutputFilter *ofilter, unsigned sched_idx_enc, break; } - ret = sch_connect(fgp->sch, SCH_FILTER_OUT(fgp->sch_idx, ofp->index), + ret = sch_connect(fgp->sch, SCH_FILTER_OUT(fgp->sch_idx, ofilter->index), SCH_ENC(sched_idx_enc)); if (ret < 0) return ret; @@ -764,16 +906,16 @@ static int ofilter_bind_ifilter(OutputFilter *ofilter, InputFilterPriv *ifp, OutputFilterPriv *ofp = ofp_from_ofilter(ofilter); av_assert0(!ofilter->bound); - av_assert0(ofilter->type == ifp->type); + av_assert0(ofilter->type == ifp->ifilter.type); ofilter->bound = 1; av_freep(&ofilter->linklabel); - ofp->name = av_strdup(opts->name); - if (!ofp->name) + ofilter->output_name = av_strdup(opts->name); + if (!ofilter->output_name) return AVERROR(EINVAL); - av_strlcatf(ofp->log_name, sizeof(ofp->log_name), "->%s", ofp->name); + av_strlcatf(ofp->log_name, sizeof(ofp->log_name), "->%s", ofilter->output_name); return 0; } @@ -789,18 +931,18 @@ static int ifilter_bind_fg(InputFilterPriv *ifp, FilterGraph *fg_src, int out_id av_assert0(!ifp->bound); ifp->bound = 1; - if (ifp->type != ofilter_src->type) { + if (ifp->ifilter.type != ofilter_src->type) { av_log(fgp, AV_LOG_ERROR, "Tried to connect %s output to %s input\n", av_get_media_type_string(ofilter_src->type), - av_get_media_type_string(ifp->type)); + av_get_media_type_string(ifp->ifilter.type)); return AVERROR(EINVAL); } - ifp->type_src = ifp->type; + ifp->type_src = ifp->ifilter.type; memset(&opts, 0, sizeof(opts)); - snprintf(name, sizeof(name), "fg:%d:%d", fgp->fg.index, ifp->index); + snprintf(name, sizeof(name), "fg:%d:%d", fgp->fg.index, ifp->ifilter.index); opts.name = name; ret = ofilter_bind_ifilter(ofilter_src, ifp, &opts); @@ -808,7 +950,7 @@ static int ifilter_bind_fg(InputFilterPriv *ifp, FilterGraph *fg_src, int out_id return ret; ret = sch_connect(fgp->sch, SCH_FILTER_OUT(fg_src->index, out_idx), - SCH_FILTER_IN(fgp->sch_idx, ifp->index)); + SCH_FILTER_IN(fgp->sch_idx, ifp->ifilter.index)); if (ret < 0) return ret; @@ -831,7 +973,7 @@ static InputFilter *ifilter_alloc(FilterGraph *fg) if (!ifp->frame) return NULL; - ifp->index = fg->nb_inputs - 1; + ifilter->index = fg->nb_inputs - 1; ifp->format = -1; ifp->color_space = AVCOL_SPC_UNSPECIFIED; ifp->color_range = AVCOL_RANGE_UNSPECIFIED; @@ -868,10 +1010,11 @@ void fg_free(FilterGraph **pfg) av_frame_free(&ifp->opts.fallback); av_buffer_unref(&ifp->hw_frames_ctx); - av_freep(&ifp->linklabel); + av_freep(&ifilter->linklabel); av_freep(&ifp->opts.name); av_frame_side_data_free(&ifp->side_data, &ifp->nb_side_data); av_freep(&ifilter->name); + av_freep(&ifilter->input_name); av_freep(&fg->inputs[j]); } av_freep(&fg->inputs); @@ -885,8 +1028,8 @@ void fg_free(FilterGraph **pfg) av_freep(&ofilter->linklabel); av_freep(&ofilter->name); + av_freep(&ofilter->output_name); av_freep(&ofilter->apad); - av_freep(&ofp->name); av_channel_layout_uninit(&ofp->ch_layout); av_frame_side_data_free(&ofp->side_data, &ofp->nb_side_data); av_freep(&fg->outputs[j]); @@ -981,21 +1124,19 @@ int fg_create(FilterGraph **pfg, char *graph_desc, Scheduler *sch) for (AVFilterInOut *cur = inputs; cur; cur = cur->next) { InputFilter *const ifilter = ifilter_alloc(fg); - InputFilterPriv *ifp; if (!ifilter) { ret = AVERROR(ENOMEM); goto fail; } - ifp = ifp_from_ifilter(ifilter); - ifp->linklabel = cur->name; + ifilter->linklabel = cur->name; cur->name = NULL; - ifp->type = avfilter_pad_get_type(cur->filter_ctx->input_pads, + ifilter->type = avfilter_pad_get_type(cur->filter_ctx->input_pads, cur->pad_idx); - if (ifp->type != AVMEDIA_TYPE_VIDEO && ifp->type != AVMEDIA_TYPE_AUDIO) { + if (ifilter->type != AVMEDIA_TYPE_VIDEO && ifilter->type != AVMEDIA_TYPE_AUDIO) { av_log(fg, AV_LOG_FATAL, "Only video and audio filters supported " "currently.\n"); ret = AVERROR(ENOSYS); @@ -1108,17 +1249,17 @@ static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter) { InputFilterPriv *ifp = ifp_from_ifilter(ifilter); InputStream *ist = NULL; - enum AVMediaType type = ifp->type; + enum AVMediaType type = ifilter->type; ViewSpecifier vs = { .type = VIEW_SPECIFIER_TYPE_NONE }; const char *spec; char *p; int i, ret; - if (ifp->linklabel && !strncmp(ifp->linklabel, "dec:", 4)) { + if (ifilter->linklabel && !strncmp(ifilter->linklabel, "dec:", 4)) { // bind to a standalone decoder int dec_idx; - dec_idx = strtol(ifp->linklabel + 4, &p, 0); + dec_idx = strtol(ifilter->linklabel + 4, &p, 0); if (dec_idx < 0 || dec_idx >= nb_decoders) { av_log(fg, AV_LOG_ERROR, "Invalid decoder index %d in filtergraph description %s\n", dec_idx, fg->graph_desc); @@ -1137,7 +1278,7 @@ static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter) av_log(fg, AV_LOG_ERROR, "Error binding a decoder to filtergraph input %s\n", ifilter->name); return ret; - } else if (ifp->linklabel) { + } else if (ifilter->linklabel) { StreamSpecifier ss; AVFormatContext *s; AVStream *st = NULL; @@ -1154,22 +1295,22 @@ static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter) OutputFilter *ofilter = fg_src->outputs[j]; if (!ofilter->bound && ofilter->linklabel && - !strcmp(ofilter->linklabel, ifp->linklabel)) { + !strcmp(ofilter->linklabel, ifilter->linklabel)) { av_log(fg, AV_LOG_VERBOSE, "Binding input with label '%s' to filtergraph output %d:%d\n", - ifp->linklabel, i, j); + ifilter->linklabel, i, j); ret = ifilter_bind_fg(ifp, fg_src, j); if (ret < 0) av_log(fg, AV_LOG_ERROR, "Error binding filtergraph input %s\n", - ifp->linklabel); + ifilter->linklabel); return ret; } } } // bind to an explicitly specified demuxer stream - file_idx = strtol(ifp->linklabel, &p, 0); + file_idx = strtol(ifilter->linklabel, &p, 0); if (file_idx < 0 || file_idx >= nb_input_files) { av_log(fg, AV_LOG_FATAL, "Invalid file index %d in filtergraph description %s.\n", file_idx, fg->graph_desc); @@ -1213,7 +1354,7 @@ static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter) av_log(fg, AV_LOG_VERBOSE, "Binding input with label '%s' to input stream %d:%d\n", - ifp->linklabel, ist->file->index, ist->index); + ifilter->linklabel, ist->file->index, ist->index); } else { ist = ist_find_unused(type); if (!ist) { @@ -1226,7 +1367,7 @@ static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter) av_log(fg, AV_LOG_VERBOSE, "Binding unlabeled input %d to input stream %d:%d\n", - ifp->index, ist->file->index, ist->index); + ifilter->index, ist->file->index, ist->index); } av_assert0(ist); @@ -1375,8 +1516,8 @@ static int configure_output_video_filter(FilterGraphPriv *fgp, AVFilterGraph *gr int ret; char name[255]; - snprintf(name, sizeof(name), "out_%s", ofp->name); - ret = avfilter_graph_create_filter(&ofp->filter, + snprintf(name, sizeof(name), "out_%s", ofilter->output_name); + ret = avfilter_graph_create_filter(&ofilter->filter, avfilter_get_by_name("buffersink"), name, NULL, NULL, graph); @@ -1395,7 +1536,7 @@ static int configure_output_video_filter(FilterGraphPriv *fgp, AVFilterGraph *gr av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value); } - snprintf(name, sizeof(name), "scaler_out_%s", ofp->name); + snprintf(name, sizeof(name), "scaler_out_%s", ofilter->output_name); if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"), name, args, NULL, graph)) < 0) return ret; @@ -1431,14 +1572,14 @@ static int configure_output_video_filter(FilterGraphPriv *fgp, AVFilterGraph *gr pad_idx = 0; } - snprintf(name, sizeof(name), "trim_out_%s", ofp->name); + snprintf(name, sizeof(name), "trim_out_%s", ofilter->output_name); ret = insert_trim(fgp, ofp->trim_start_us, ofp->trim_duration_us, &last_filter, &pad_idx, name); if (ret < 0) return ret; - if ((ret = avfilter_link(last_filter, pad_idx, ofp->filter, 0)) < 0) + if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0) return ret; return 0; @@ -1454,8 +1595,8 @@ static int configure_output_audio_filter(FilterGraphPriv *fgp, AVFilterGraph *gr char name[255]; int ret; - snprintf(name, sizeof(name), "out_%s", ofp->name); - ret = avfilter_graph_create_filter(&ofp->filter, + snprintf(name, sizeof(name), "out_%s", ofilter->output_name); + ret = avfilter_graph_create_filter(&ofilter->filter, avfilter_get_by_name("abuffersink"), name, NULL, NULL, graph); if (ret < 0) @@ -1492,7 +1633,7 @@ static int configure_output_audio_filter(FilterGraphPriv *fgp, AVFilterGraph *gr if (args.len) { AVFilterContext *format; - snprintf(name, sizeof(name), "format_out_%s", ofp->name); + snprintf(name, sizeof(name), "format_out_%s", ofilter->output_name); ret = avfilter_graph_create_filter(&format, avfilter_get_by_name("aformat"), name, args.str, NULL, graph); @@ -1512,13 +1653,13 @@ static int configure_output_audio_filter(FilterGraphPriv *fgp, AVFilterGraph *gr fgp->have_sources = 1; } - snprintf(name, sizeof(name), "trim for output %s", ofp->name); + snprintf(name, sizeof(name), "trim for output %s", ofilter->output_name); ret = insert_trim(fgp, ofp->trim_start_us, ofp->trim_duration_us, &last_filter, &pad_idx, name); if (ret < 0) goto fail; - if ((ret = avfilter_link(last_filter, pad_idx, ofp->filter, 0)) < 0) + if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0) goto fail; fail: av_bprint_finalize(&args, NULL); @@ -1567,8 +1708,8 @@ static int configure_input_video_filter(FilterGraph *fg, AVFilterGraph *graph, snprintf(name, sizeof(name), "graph %d input from stream %s", fg->index, ifp->opts.name); - ifp->filter = avfilter_graph_alloc_filter(graph, buffer_filt, name); - if (!ifp->filter) { + ifilter->filter = avfilter_graph_alloc_filter(graph, buffer_filt, name); + if (!ifilter->filter) { ret = AVERROR(ENOMEM); goto fail; } @@ -1586,16 +1727,16 @@ static int configure_input_video_filter(FilterGraph *fg, AVFilterGraph *graph, par->side_data = ifp->side_data; par->nb_side_data = ifp->nb_side_data; - ret = av_buffersrc_parameters_set(ifp->filter, par); + ret = av_buffersrc_parameters_set(ifilter->filter, par); if (ret < 0) goto fail; av_freep(&par); - ret = avfilter_init_dict(ifp->filter, NULL); + ret = avfilter_init_dict(ifilter->filter, NULL); if (ret < 0) goto fail; - last_filter = ifp->filter; + last_filter = ifilter->filter; desc = av_pix_fmt_desc_get(ifp->format); av_assert0(desc); @@ -1689,7 +1830,7 @@ static int configure_input_audio_filter(FilterGraph *fg, AVFilterGraph *graph, av_bprintf(&args, ":channels=%d", ifp->ch_layout.nb_channels); snprintf(name, sizeof(name), "graph_%d_in_%s", fg->index, ifp->opts.name); - if ((ret = avfilter_graph_create_filter(&ifp->filter, abuffer_filt, + if ((ret = avfilter_graph_create_filter(&ifilter->filter, abuffer_filt, name, args.str, NULL, graph)) < 0) return ret; @@ -1698,11 +1839,11 @@ static int configure_input_audio_filter(FilterGraph *fg, AVFilterGraph *graph, return AVERROR(ENOMEM); par->side_data = ifp->side_data; par->nb_side_data = ifp->nb_side_data; - ret = av_buffersrc_parameters_set(ifp->filter, par); + ret = av_buffersrc_parameters_set(ifilter->filter, par); av_free(par); if (ret < 0) return ret; - last_filter = ifp->filter; + last_filter = ifilter->filter; snprintf(name, sizeof(name), "trim for input stream %s", ifp->opts.name); ret = insert_trim(fg, ifp->opts.trim_start_us, ifp->opts.trim_end_us, @@ -1719,7 +1860,7 @@ static int configure_input_audio_filter(FilterGraph *fg, AVFilterGraph *graph, static int configure_input_filter(FilterGraph *fg, AVFilterGraph *graph, InputFilter *ifilter, AVFilterInOut *in) { - switch (ifp_from_ifilter(ifilter)->type) { + switch (ifilter->type) { case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, graph, ifilter, in); case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, graph, ifilter, in); default: av_assert0(0); return 0; @@ -1729,9 +1870,9 @@ static int configure_input_filter(FilterGraph *fg, AVFilterGraph *graph, static void cleanup_filtergraph(FilterGraph *fg, FilterGraphThread *fgt) { for (int i = 0; i < fg->nb_outputs; i++) - ofp_from_ofilter(fg->outputs[i])->filter = NULL; + fg->outputs[i]->filter = NULL; for (int i = 0; i < fg->nb_inputs; i++) - ifp_from_ifilter(fg->inputs[i])->filter = NULL; + fg->inputs[i]->filter = NULL; avfilter_graph_free(&fgt->graph); } @@ -1845,7 +1986,7 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt) int nb_sd; OutputFilter *ofilter = fg->outputs[i]; OutputFilterPriv *ofp = ofp_from_ofilter(ofilter); - AVFilterContext *sink = ofp->filter; + AVFilterContext *sink = ofilter->filter; ofp->format = av_buffersink_get_format(sink); @@ -1885,6 +2026,7 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt) } for (int i = 0; i < fg->nb_inputs; i++) { + InputFilter *ifilter = fg->inputs[i]; InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]); AVFrame *tmp; while (av_fifo_read(ifp->frame_queue, &tmp, 1) >= 0) { @@ -1895,7 +2037,7 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt) if (ifp->displaymatrix_applied) av_frame_remove_side_data(tmp, AV_FRAME_DATA_DISPLAYMATRIX); } - ret = av_buffersrc_add_frame(ifp->filter, tmp); + ret = av_buffersrc_add_frame(ifilter->filter, tmp); } av_frame_free(&tmp); if (ret < 0) @@ -1905,9 +2047,9 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt) /* send the EOFs for the finished inputs */ for (int i = 0; i < fg->nb_inputs; i++) { - InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]); + InputFilter *ifilter = fg->inputs[i]; if (fgt->eof_in[i]) { - ret = av_buffersrc_add_frame(ifp->filter, NULL); + ret = av_buffersrc_add_frame(ifilter->filter, NULL); if (ret < 0) goto fail; have_input_eof = 1; @@ -1937,7 +2079,7 @@ static int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *fr if (ret < 0) return ret; - ifp->time_base = (ifp->type == AVMEDIA_TYPE_AUDIO) ? (AVRational){ 1, frame->sample_rate } : + ifp->time_base = (ifilter->type == AVMEDIA_TYPE_AUDIO) ? (AVRational){ 1, frame->sample_rate } : (ifp->opts.flags & IFILTER_FLAG_CFR) ? av_inv_q(ifp->opts.framerate) : frame->time_base; @@ -2027,12 +2169,11 @@ static int choose_input(const FilterGraph *fg, const FilterGraphThread *fgt) for (int i = 0; i < fg->nb_inputs; i++) { InputFilter *ifilter = fg->inputs[i]; - InputFilterPriv *ifp = ifp_from_ifilter(ifilter); if (fgt->eof_in[i]) continue; - nb_requests = av_buffersrc_get_nb_failed_requests(ifp->filter); + nb_requests = av_buffersrc_get_nb_failed_requests(ifilter->filter); if (nb_requests > nb_requests_max) { nb_requests_max = nb_requests; best_input = i; @@ -2076,7 +2217,7 @@ static int choose_out_timebase(OutputFilterPriv *ofp, AVFrame *frame) fr = fps->framerate; if (!fr.num) { - AVRational fr_sink = av_buffersink_get_frame_rate(ofp->filter); + AVRational fr_sink = av_buffersink_get_frame_rate(ofilter->filter); if (fr_sink.num > 0 && fr_sink.den > 0) fr = fr_sink; } @@ -2329,16 +2470,16 @@ static int close_output(OutputFilterPriv *ofp, FilterGraphThread *fgt) "No filtered frames for output stream, trying to " "initialize anyway.\n"); - ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->index, frame); + ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, frame); if (ret < 0) { av_frame_unref(frame); return ret; } } - fgt->eof_out[ofp->index] = 1; + fgt->eof_out[ofp->ofilter.index] = 1; - ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->index, NULL); + ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, NULL); return (ret == AVERROR_EOF) ? 0 : ret; } @@ -2391,12 +2532,12 @@ static int fg_output_frame(OutputFilterPriv *ofp, FilterGraphThread *fgt, } // send the frame to consumers - ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->index, frame_out); + ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, frame_out); if (ret < 0) { av_frame_unref(frame_out); - if (!fgt->eof_out[ofp->index]) { - fgt->eof_out[ofp->index] = 1; + if (!fgt->eof_out[ofp->ofilter.index]) { + fgt->eof_out[ofp->ofilter.index] = 1; fgp->nb_outputs_done++; } @@ -2429,13 +2570,13 @@ static int fg_output_step(OutputFilterPriv *ofp, FilterGraphThread *fgt, AVFrame *frame) { FilterGraphPriv *fgp = fgp_from_fg(ofp->ofilter.graph); - AVFilterContext *filter = ofp->filter; + AVFilterContext *filter = ofp->ofilter.filter; FrameData *fd; int ret; ret = av_buffersink_get_frame_flags(filter, frame, AV_BUFFERSINK_FLAG_NO_REQUEST); - if (ret == AVERROR_EOF && !fgt->eof_out[ofp->index]) { + if (ret == AVERROR_EOF && !fgt->eof_out[ofp->ofilter.index]) { ret = fg_output_frame(ofp, fgt, NULL); return (ret < 0) ? ret : 1; } else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { @@ -2447,7 +2588,7 @@ static int fg_output_step(OutputFilterPriv *ofp, FilterGraphThread *fgt, return ret; } - if (fgt->eof_out[ofp->index]) { + if (fgt->eof_out[ofp->ofilter.index]) { av_frame_unref(frame); return 0; } @@ -2622,7 +2763,7 @@ static int sub2video_frame(InputFilter *ifilter, AVFrame *frame, int buffer) 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(ifilter->filter, NULL); } ifp->width = frame->width ? frame->width : ifp->width; @@ -2639,16 +2780,16 @@ static int send_eof(FilterGraphThread *fgt, InputFilter *ifilter, InputFilterPriv *ifp = ifp_from_ifilter(ifilter); int ret; - if (fgt->eof_in[ifp->index]) + if (fgt->eof_in[ifilter->index]) return 0; - fgt->eof_in[ifp->index] = 1; + fgt->eof_in[ifilter->index] = 1; - if (ifp->filter) { + if (ifilter->filter) { pts = av_rescale_q_rnd(pts, tb, ifp->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); - ret = av_buffersrc_close(ifp->filter, pts, AV_BUFFERSRC_FLAG_PUSH); + ret = av_buffersrc_close(ifilter->filter, pts, AV_BUFFERSRC_FLAG_PUSH); if (ret < 0) return ret; } else { @@ -2717,7 +2858,7 @@ static int send_frame(FilterGraph *fg, FilterGraphThread *fgt, int need_reinit = 0, ret; /* determine if the parameters for this input changed */ - switch (ifp->type) { + switch (ifilter->type) { case AVMEDIA_TYPE_AUDIO: if (ifp->format != frame->format || ifp->sample_rate != frame->sample_rate || @@ -2837,7 +2978,7 @@ static int send_frame(FilterGraph *fg, FilterGraphThread *fgt, return AVERROR(ENOMEM); fd->wallclock[LATENCY_PROBE_FILTER_PRE] = av_gettime_relative(); - ret = av_buffersrc_add_frame_flags(ifp->filter, frame, + ret = av_buffersrc_add_frame_flags(ifilter->filter, frame, AV_BUFFERSRC_FLAG_PUSH); if (ret < 0) { av_frame_unref(frame); @@ -2856,7 +2997,7 @@ static void fg_thread_set_name(const FilterGraph *fg) OutputFilterPriv *ofp = ofp_from_ofilter(fg->outputs[0]); snprintf(name, sizeof(name), "%cf%s", av_get_media_type_string(ofp->ofilter.type)[0], - ofp->name); + ofp->ofilter.output_name); } else { snprintf(name, sizeof(name), "fc%d", fg->index); } diff --git a/fftools/ffmpeg_filter.h b/fftools/ffmpeg_filter.h deleted file mode 100644 index bf690bdc91..0000000000 --- a/fftools/ffmpeg_filter.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef FFTOOLS_FFMPEG_FILTER_H -#define FFTOOLS_FFMPEG_FILTER_H - -#include "ffmpeg.h" - -#include - -#include "ffmpeg_sched.h" -#include "sync_queue.h" - -#include "libavfilter/avfilter.h" - -#include "libavutil/avutil.h" -#include "libavutil/dict.h" -#include "libavutil/fifo.h" -#include "libavutil/pixfmt.h" -#include "libavutil/rational.h" -#include "libavutil/bprint.h" -#include "libavutil/channel_layout.h" -#include "libavutil/downmix_info.h" - -typedef struct InputFilterPriv { - InputFilter ifilter; - - InputFilterOptions opts; - - int index; - - AVFilterContext *filter; - - // used to hold submitted input - AVFrame *frame; - - /* for filters that are not yet bound to an input stream, - * this stores the input linklabel, if any */ - uint8_t *linklabel; - - // filter data type - enum AVMediaType type; - // source data type: AVMEDIA_TYPE_SUBTITLE for sub2video, - // same as type otherwise - enum AVMediaType type_src; - - int eof; - int bound; - int drop_warned; - uint64_t nb_dropped; - - // parameters configured for this input - int format; - - int width, height; - AVRational sample_aspect_ratio; - enum AVColorSpace color_space; - enum AVColorRange color_range; - - int sample_rate; - AVChannelLayout ch_layout; - - AVRational time_base; - - AVFrameSideData **side_data; - int nb_side_data; - - AVFifo *frame_queue; - - AVBufferRef *hw_frames_ctx; - - int displaymatrix_present; - int displaymatrix_applied; - int32_t displaymatrix[9]; - - int downmixinfo_present; - AVDownmixInfo downmixinfo; - - struct { - AVFrame *frame; - - int64_t last_pts; - int64_t end_pts; - - /// marks if sub2video_update should force an initialization - unsigned int initialize; - } sub2video; -} InputFilterPriv; - -static inline InputFilterPriv *ifp_from_ifilter(InputFilter *ifilter) -{ - return (InputFilterPriv*)ifilter; -} - -typedef struct FPSConvContext { - AVFrame *last_frame; - /* number of frames emitted by the video-encoding sync code */ - int64_t frame_number; - /* history of nb_frames_prev, i.e. the number of times the - * previous frame was duplicated by vsync code in recent - * do_video_out() calls */ - int64_t frames_prev_hist[3]; - - uint64_t dup_warning; - - int last_dropped; - int dropped_keyframe; - - enum VideoSyncMethod vsync_method; - - AVRational framerate; - AVRational framerate_max; - const AVRational *framerate_supported; - int framerate_clip; -} FPSConvContext; - - -typedef struct OutputFilterPriv { - OutputFilter ofilter; - - int index; - - void *log_parent; - char log_name[32]; - - char *name; - - AVFilterContext *filter; - - /* desired output stream properties */ - int format; - int width, height; - int sample_rate; - AVChannelLayout ch_layout; - enum AVColorSpace color_space; - enum AVColorRange color_range; - - AVFrameSideData **side_data; - int nb_side_data; - - // time base in which the output is sent to our downstream - // does not need to match the filtersink's timebase - AVRational tb_out; - // at least one frame with the above timebase was sent - // to our downstream, so it cannot change anymore - int tb_out_locked; - - AVRational sample_aspect_ratio; - - AVDictionary *sws_opts; - AVDictionary *swr_opts; - - // those are only set if no format is specified and the encoder gives us multiple options - // They point directly to the relevant lists of the encoder. - const int *formats; - const AVChannelLayout *ch_layouts; - const int *sample_rates; - const enum AVColorSpace *color_spaces; - const enum AVColorRange *color_ranges; - - AVRational enc_timebase; - int64_t trim_start_us; - int64_t trim_duration_us; - // offset for output timestamps, in AV_TIME_BASE_Q - int64_t ts_offset; - int64_t next_pts; - FPSConvContext fps; - - unsigned flags; -} OutputFilterPriv; - -static inline OutputFilterPriv *ofp_from_ofilter(OutputFilter *ofilter) -{ - return (OutputFilterPriv*)ofilter; -} - -#endif /* FFTOOLS_FFMPEG_FILTER_H */ diff --git a/fftools/graph/graphprint.c b/fftools/graph/graphprint.c index e55c8d7507..423878326d 100644 --- a/fftools/graph/graphprint.c +++ b/fftools/graph/graphprint.c @@ -28,7 +28,7 @@ #include "graphprint.h" -#include "fftools/ffmpeg_filter.h" +#include "fftools/ffmpeg.h" #include "fftools/ffmpeg_mux.h" #include "libavutil/avassert.h" @@ -490,7 +490,7 @@ static void print_filtergraph_single(GraphPrintContext *gpc, FilterGraph *fg, AV print_section_header_id(gpc, SECTION_ID_GRAPH_INPUTS, "Input_File", 0); for (int i = 0; i < fg->nb_inputs; i++) { - InputFilterPriv *ifilter = ifp_from_ifilter(fg->inputs[i]); + InputFilter *ifilter = fg->inputs[i]; enum AVMediaType media_type = ifilter->type; avtext_print_section_header(tfc, NULL, SECTION_ID_GRAPH_INPUT); @@ -507,8 +507,8 @@ static void print_filtergraph_single(GraphPrintContext *gpc, FilterGraph *fg, AV if (ifilter->linklabel && ifilter->filter) av_dict_set(&input_map, ifilter->filter->name, (const char *)ifilter->linklabel, 0); - else if (ifilter->opts.name && ifilter->filter) - av_dict_set(&input_map, ifilter->filter->name, (const char *)ifilter->opts.name, 0); + else if (ifilter->input_name && ifilter->filter) + av_dict_set(&input_map, ifilter->filter->name, (const char *)ifilter->input_name, 0); print_str("media_type", av_get_media_type_string(media_type)); @@ -520,13 +520,13 @@ static void print_filtergraph_single(GraphPrintContext *gpc, FilterGraph *fg, AV print_section_header_id(gpc, SECTION_ID_GRAPH_OUTPUTS, "Output_File", 0); for (int i = 0; i < fg->nb_outputs; i++) { - OutputFilterPriv *ofilter = ofp_from_ofilter(fg->outputs[i]); + OutputFilter *ofilter = fg->outputs[i]; avtext_print_section_header(tfc, NULL, SECTION_ID_GRAPH_OUTPUT); print_int("output_index", ofilter->index); - print_str("name", ofilter->name); + print_str("name", ofilter->output_name); if (fg->outputs[i]->linklabel) print_str("link_label", (const char*)fg->outputs[i]->linklabel); @@ -536,11 +536,11 @@ static void print_filtergraph_single(GraphPrintContext *gpc, FilterGraph *fg, AV print_str("filter_name", ofilter->filter->filter->name); } - if (ofilter->name && ofilter->filter) - av_dict_set(&output_map, ofilter->filter->name, ofilter->name, 0); + if (ofilter->output_name && ofilter->filter) + av_dict_set(&output_map, ofilter->filter->name, ofilter->output_name, 0); - print_str("media_type", av_get_media_type_string(fg->outputs[i]->type)); + print_str("media_type", av_get_media_type_string(ofilter->type)); avtext_print_section_footer(tfc); // SECTION_ID_GRAPH_OUTPUT } diff --git a/fftools/resources/resman.c b/fftools/resources/resman.c index a9e21626fa..bce3589169 100644 --- a/fftools/resources/resman.c +++ b/fftools/resources/resman.c @@ -32,7 +32,6 @@ #endif #include "resman.h" -#include "fftools/ffmpeg_filter.h" #include "libavutil/avassert.h" #include "libavutil/pixdesc.h" #include "libavutil/dict.h" From git at videolan.org Mon Jun 2 01:58:19 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Sun, 01 Jun 2025 22:58:19 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?fftools/graph/graphprint=3A_Fix_races_?= =?utf-8?q?when_initializing_graphprint?= Message-ID: <20250601225820.BEE3F412A75@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Fri May 30 16:02:08 2025 +0200| [0742239289b0d29d219cdb1f80ff1e0a345052d4] | committer: Andreas Rheinhardt fftools/graph/graphprint: Fix races when initializing graphprint Setting print_graphs_format (in case no -print_graphs_format option was specified) is racy, as is using av_strtok() to split it. Both have been removed. Notice that using av_strtok() was destructive: In the absence of races the options would only have been applied for the first initialization. Reviewed-by: softworkz . Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=0742239289b0d29d219cdb1f80ff1e0a345052d4 --- fftools/graph/graphprint.c | 19 ++++--------------- fftools/textformat/avtextformat.c | 7 +++++-- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/fftools/graph/graphprint.c b/fftools/graph/graphprint.c index 423878326d..7f0e85d008 100644 --- a/fftools/graph/graphprint.c +++ b/fftools/graph/graphprint.c @@ -874,8 +874,6 @@ static int init_graphprint(GraphPrintContext **pgpc, AVBPrint *target_buf) AVTextFormatContext *tfc = NULL; AVTextWriterContext *wctx = NULL; GraphPrintContext *gpc = NULL; - char *w_args = NULL; - char *w_name; int ret; init_sections(); @@ -883,19 +881,7 @@ static int init_graphprint(GraphPrintContext **pgpc, AVBPrint *target_buf) av_bprint_init(target_buf, 0, AV_BPRINT_SIZE_UNLIMITED); - if (!print_graphs_format) - print_graphs_format = av_strdup("json"); - if (!print_graphs_format) { - ret = AVERROR(ENOMEM); - goto fail; - } - - w_name = av_strtok(print_graphs_format, "=", &w_args); - if (!w_name) { - av_log(NULL, AV_LOG_ERROR, "No name specified for the filter graph output format\n"); - ret = AVERROR(EINVAL); - goto fail; - } + const char *w_name = print_graphs_format ? print_graphs_format : "json"; text_formatter = avtext_get_formatter_by_name(w_name); if (!text_formatter) { @@ -912,6 +898,9 @@ static int init_graphprint(GraphPrintContext **pgpc, AVBPrint *target_buf) } AVTextFormatOptions tf_options = { .show_optional_fields = -1 }; + const char *w_args = print_graphs_format ? strchr(print_graphs_format, '=') : NULL; + if (w_args) + ++w_args; // consume '=' ret = avtext_context_open(&tfc, text_formatter, wctx, w_args, sections, FF_ARRAY_ELEMS(sections), tf_options, NULL); if (ret < 0) { goto fail; diff --git a/fftools/textformat/avtextformat.c b/fftools/textformat/avtextformat.c index bb90e66918..e8e43c3c37 100644 --- a/fftools/textformat/avtextformat.c +++ b/fftools/textformat/avtextformat.c @@ -706,9 +706,12 @@ const AVTextFormatter *avtext_get_formatter_by_name(const char *name) { formatters_register_all(); - for (int i = 0; registered_formatters[i]; i++) - if (!strcmp(registered_formatters[i]->name, name)) + for (int i = 0; registered_formatters[i]; i++) { + const char *end; + if (av_strstart(name, registered_formatters[i]->name, &end) && + (*end == '\0' || *end == '=')) return registered_formatters[i]; + } return NULL; } From git at videolan.org Mon Jun 2 01:58:21 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Sun, 01 Jun 2025 22:58:21 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?fftools/textformat/avtextformat=3A_Avo?= =?utf-8?q?id_relocations?= Message-ID: <20250601225822.CE46F412A83@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Sun Jun 1 03:33:00 2025 +0200| [b4c5397642416889872f4f2238941874f33ee0db] | committer: Andreas Rheinhardt fftools/textformat/avtextformat: Avoid relocations Reviewed-by: softworkz . Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b4c5397642416889872f4f2238941874f33ee0db --- fftools/textformat/avtextformat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fftools/textformat/avtextformat.c b/fftools/textformat/avtextformat.c index e8e43c3c37..0b61d353db 100644 --- a/fftools/textformat/avtextformat.c +++ b/fftools/textformat/avtextformat.c @@ -43,8 +43,8 @@ static const struct { double bin_val; double dec_val; - const char *bin_str; - const char *dec_str; + char bin_str[4]; + char dec_str[4]; } si_prefixes[] = { { 1.0, 1.0, "", "" }, { 1.024e3, 1e3, "Ki", "K" }, From git at videolan.org Mon Jun 2 01:58:23 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Sun, 01 Jun 2025 22:58:23 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?fftools/resources/resman=3A_Don=27t_al?= =?utf-8?q?loc_ResourceManager=2C_fix_race?= Message-ID: <20250601225824.D6AC0412B04@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Sun Jun 1 04:15:58 2025 +0200| [06cd9086c32bf6654f609604ac6131bbd4487803] | committer: Andreas Rheinhardt fftools/resources/resman: Don't alloc ResourceManager, fix race The resman_ctx pointer was accessed outside of its guarding mutex. Also make the ResourceManager static. Reviewed-by: softworkz . Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=06cd9086c32bf6654f609604ac6131bbd4487803 --- fftools/resources/resman.c | 37 +++---------------------------------- 1 file changed, 3 insertions(+), 34 deletions(-) diff --git a/fftools/resources/resman.c b/fftools/resources/resman.c index bce3589169..92e91a39d9 100644 --- a/fftools/resources/resman.c +++ b/fftools/resources/resman.c @@ -60,7 +60,7 @@ typedef struct ResourceManagerContext { static AVMutex mutex = AV_MUTEX_INITIALIZER; -ResourceManagerContext *resman_ctx = NULL; +static ResourceManagerContext resman_ctx = { .class = &resman_class }; #if CONFIG_RESOURCE_COMPRESSION @@ -117,39 +117,11 @@ static int decompress_gzip(ResourceManagerContext *ctx, uint8_t *in, unsigned in } #endif -static ResourceManagerContext *get_resman_context(void) -{ - ResourceManagerContext *res = resman_ctx; - - ff_mutex_lock(&mutex); - - if (res) - goto end; - - res = av_mallocz(sizeof(ResourceManagerContext)); - if (!res) { - av_log(NULL, AV_LOG_ERROR, "Failed to allocate resource manager context\n"); - goto end; - } - - res->class = &resman_class; - resman_ctx = res; - -end: - ff_mutex_unlock(&mutex); - return res; -} - - void ff_resman_uninit(void) { ff_mutex_lock(&mutex); - if (resman_ctx) { - if (resman_ctx->resource_dic) - av_dict_free(&resman_ctx->resource_dic); - av_freep(&resman_ctx); - } + av_dict_free(&resman_ctx.resource_dic); ff_mutex_unlock(&mutex); } @@ -157,14 +129,11 @@ void ff_resman_uninit(void) char *ff_resman_get_string(FFResourceId resource_id) { - ResourceManagerContext *ctx = get_resman_context(); + ResourceManagerContext *ctx = &resman_ctx; FFResourceDefinition resource_definition = { 0 }; AVDictionaryEntry *dic_entry; char *res = NULL; - if (!ctx) - return NULL; - for (unsigned i = 0; i < FF_ARRAY_ELEMS(resource_definitions); ++i) { FFResourceDefinition def = resource_definitions[i]; if (def.resource_id == resource_id) { From git at videolan.org Mon Jun 2 01:58:25 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Sun, 01 Jun 2025 22:58:25 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?fftools/resources/resman=3A_Use_assert?= =?utf-8?q?_for_always-false_condition?= Message-ID: <20250601225826.E23AD412A75@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Sun Jun 1 04:20:32 2025 +0200| [6d5e18b2f35219dce2d54726a59c47e1c4363a25] | committer: Andreas Rheinhardt fftools/resources/resman: Use assert for always-false condition Reviewed-by: softworkz . Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=6d5e18b2f35219dce2d54726a59c47e1c4363a25 --- fftools/resources/resman.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fftools/resources/resman.c b/fftools/resources/resman.c index 92e91a39d9..c1648dd643 100644 --- a/fftools/resources/resman.c +++ b/fftools/resources/resman.c @@ -142,10 +142,7 @@ char *ff_resman_get_string(FFResourceId resource_id) } } - if (!resource_definition.name) { - av_log(ctx, AV_LOG_ERROR, "Unable to find resource with ID %d\n", resource_id); - return NULL; - } + av_assert1(resource_definition.name); ff_mutex_lock(&mutex); From git at videolan.org Mon Jun 2 01:58:29 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Sun, 01 Jun 2025 22:58:29 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?fftools/textformat/avtextformat=3A_Fix?= =?utf-8?q?_races_when_initializing_formatters?= Message-ID: <20250601225831.0748E412B0B@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Sun Jun 1 04:28:12 2025 +0200| [6f452ad1acadc50abc7d9b1b9d264e940a451ee7] | committer: Andreas Rheinhardt fftools/textformat/avtextformat: Fix races when initializing formatters Reviewed-by: softworkz . Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=6f452ad1acadc50abc7d9b1b9d264e940a451ee7 --- fftools/textformat/avtextformat.c | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/fftools/textformat/avtextformat.c b/fftools/textformat/avtextformat.c index 0b61d353db..14779e6f0c 100644 --- a/fftools/textformat/avtextformat.c +++ b/fftools/textformat/avtextformat.c @@ -681,31 +681,22 @@ fail: return ret; } -static const AVTextFormatter *registered_formatters[9 + 1]; - -static void formatters_register_all(void) +static const AVTextFormatter *const registered_formatters[] = { - static int initialized; - - if (initialized) - return; - initialized = 1; - - registered_formatters[0] = &avtextformatter_default; - registered_formatters[1] = &avtextformatter_compact; - registered_formatters[2] = &avtextformatter_csv; - registered_formatters[3] = &avtextformatter_flat; - registered_formatters[4] = &avtextformatter_ini; - registered_formatters[5] = &avtextformatter_json; - registered_formatters[6] = &avtextformatter_xml; - registered_formatters[7] = &avtextformatter_mermaid; - registered_formatters[8] = &avtextformatter_mermaidhtml; -} + &avtextformatter_default, + &avtextformatter_compact, + &avtextformatter_csv, + &avtextformatter_flat, + &avtextformatter_ini, + &avtextformatter_json, + &avtextformatter_xml, + &avtextformatter_mermaid, + &avtextformatter_mermaidhtml, + NULL +}; const AVTextFormatter *avtext_get_formatter_by_name(const char *name) { - formatters_register_all(); - for (int i = 0; registered_formatters[i]; i++) { const char *end; if (av_strstart(name, registered_formatters[i]->name, &end) && From git at videolan.org Mon Jun 2 01:58:27 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Sun, 01 Jun 2025 22:58:27 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?fftools/resources/resman=3A_Use_proper?= =?utf-8?q?_logcontext?= Message-ID: <20250601225828.EED4A412A83@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Sun Jun 1 13:06:14 2025 +0200| [4947e569748b3093b4dee3ede3e9525a179a49e7] | committer: Andreas Rheinhardt fftools/resources/resman: Use proper logcontext Reviewed-by: softworkz . Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4947e569748b3093b4dee3ede3e9525a179a49e7 --- fftools/resources/resman.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fftools/resources/resman.c b/fftools/resources/resman.c index c1648dd643..aa53e96bf4 100644 --- a/fftools/resources/resman.c +++ b/fftools/resources/resman.c @@ -159,13 +159,13 @@ char *ff_resman_get_string(FFResourceId resource_id) int ret = decompress_gzip(ctx, (uint8_t *)resource_definition.data, *resource_definition.data_len, &out, &out_len); if (ret) { - av_log(NULL, AV_LOG_ERROR, "Unable to decompress the resource with ID %d\n", resource_id); + av_log(ctx, AV_LOG_ERROR, "Unable to decompress the resource with ID %d\n", resource_id); goto end; } dict_ret = av_dict_set(&ctx->resource_dic, resource_definition.name, out, 0); if (dict_ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Failed to store decompressed resource in dictionary: %d\n", dict_ret); + av_log(ctx, AV_LOG_ERROR, "Failed to store decompressed resource in dictionary: %d\n", dict_ret); av_freep(&out); goto end; } @@ -175,7 +175,7 @@ char *ff_resman_get_string(FFResourceId resource_id) dict_ret = av_dict_set(&ctx->resource_dic, resource_definition.name, (const char *)resource_definition.data, 0); if (dict_ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Failed to store resource in dictionary: %d\n", dict_ret); + av_log(ctx, AV_LOG_ERROR, "Failed to store resource in dictionary: %d\n", dict_ret); goto end; } @@ -183,7 +183,7 @@ char *ff_resman_get_string(FFResourceId resource_id) dic_entry = av_dict_get(ctx->resource_dic, resource_definition.name, NULL, 0); if (!dic_entry) { - av_log(NULL, AV_LOG_ERROR, "Failed to retrieve resource from dictionary after storing it\n"); + av_log(ctx, AV_LOG_ERROR, "Failed to retrieve resource from dictionary after storing it\n"); goto end; } } From git at videolan.org Mon Jun 2 01:58:32 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Sun, 01 Jun 2025 22:58:32 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?fftools/ffprobe=3A_Factor_writing_comm?= =?utf-8?q?on_side_data_types_out?= Message-ID: <20250601225833.160D8412B04@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Sun Jun 1 04:54:45 2025 +0200| [5c5c7dff2b3457bc5253c599e30370c38d1eeaf7] | committer: Andreas Rheinhardt fftools/ffprobe: Factor writing common side data types out Reviewed-by: softworkz . Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5c5c7dff2b3457bc5253c599e30370c38d1eeaf7 --- fftools/ffprobe.c | 95 +++++++++++++++++++++++++------------------------------ 1 file changed, 43 insertions(+), 52 deletions(-) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 80ce38e73b..751fbf1771 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -457,6 +457,43 @@ static inline int show_tags(AVTextFormatContext *tfc, AVDictionary *tags, int se return ret; } +static void print_displaymatrix(AVTextFormatContext *tfc, const int32_t matrix[9]) +{ + double rotation = av_display_rotation_get(matrix); + if (isnan(rotation)) + rotation = 0; + avtext_print_integers(tfc, "displaymatrix", (void*)matrix, 9, " %11d", 3, 4, 1); + print_int("rotation", rotation); +} + +static void print_mastering_display_metadata(AVTextFormatContext *tfc, + const AVMasteringDisplayMetadata *metadata) +{ + if (metadata->has_primaries) { + print_q("red_x", metadata->display_primaries[0][0], '/'); + print_q("red_y", metadata->display_primaries[0][1], '/'); + print_q("green_x", metadata->display_primaries[1][0], '/'); + print_q("green_y", metadata->display_primaries[1][1], '/'); + print_q("blue_x", metadata->display_primaries[2][0], '/'); + print_q("blue_y", metadata->display_primaries[2][1], '/'); + + print_q("white_point_x", metadata->white_point[0], '/'); + print_q("white_point_y", metadata->white_point[1], '/'); + } + + if (metadata->has_luminance) { + print_q("min_luminance", metadata->min_luminance, '/'); + print_q("max_luminance", metadata->max_luminance, '/'); + } +} + +static void print_context_light_level(AVTextFormatContext *tfc, + const AVContentLightMetadata *metadata) +{ + print_int("max_content", metadata->MaxCLL); + print_int("max_average", metadata->MaxFALL); +} + static void print_dovi_metadata(AVTextFormatContext *tfc, const AVDOVIMetadata *dovi) { if (!dovi) @@ -934,11 +971,7 @@ static void print_pkt_side_data(AVTextFormatContext *tfc, avtext_print_section_header(tfc, sd, id_data); print_str("side_data_type", name ? name : "unknown"); if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9*4) { - double rotation = av_display_rotation_get((int32_t *)sd->data); - if (isnan(rotation)) - rotation = 0; - avtext_print_integers(tfc, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1); - print_int("rotation", rotation); + print_displaymatrix(tfc, (const int32_t*)sd->data); } else if (sd->type == AV_PKT_DATA_STEREO3D) { const AVStereo3D *stereo = (AVStereo3D *)sd->data; print_str("type", av_stereo3d_type_name(stereo->type)); @@ -972,28 +1005,9 @@ static void print_pkt_side_data(AVTextFormatContext *tfc, print_int("skip_reason", AV_RL8(sd->data + 8)); print_int("discard_reason", AV_RL8(sd->data + 9)); } else if (sd->type == AV_PKT_DATA_MASTERING_DISPLAY_METADATA) { - AVMasteringDisplayMetadata *metadata = (AVMasteringDisplayMetadata *)sd->data; - - if (metadata->has_primaries) { - print_q("red_x", metadata->display_primaries[0][0], '/'); - print_q("red_y", metadata->display_primaries[0][1], '/'); - print_q("green_x", metadata->display_primaries[1][0], '/'); - print_q("green_y", metadata->display_primaries[1][1], '/'); - print_q("blue_x", metadata->display_primaries[2][0], '/'); - print_q("blue_y", metadata->display_primaries[2][1], '/'); - - print_q("white_point_x", metadata->white_point[0], '/'); - print_q("white_point_y", metadata->white_point[1], '/'); - } - - if (metadata->has_luminance) { - print_q("min_luminance", metadata->min_luminance, '/'); - print_q("max_luminance", metadata->max_luminance, '/'); - } + print_mastering_display_metadata(tfc, (AVMasteringDisplayMetadata *)sd->data); } else if (sd->type == AV_PKT_DATA_CONTENT_LIGHT_LEVEL) { - AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data; - print_int("max_content", metadata->MaxCLL); - print_int("max_average", metadata->MaxFALL); + print_context_light_level(tfc, (AVContentLightMetadata *)sd->data); } else if (sd->type == AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT) { print_ambient_viewing_environment( tfc, (const AVAmbientViewingEnvironment *)sd->data); @@ -1279,11 +1293,7 @@ static void print_frame_side_data(AVTextFormatContext *tfc, name = av_frame_side_data_name(sd->type); print_str("side_data_type", name ? name : "unknown"); if (sd->type == AV_FRAME_DATA_DISPLAYMATRIX && sd->size >= 9*4) { - double rotation = av_display_rotation_get((int32_t *)sd->data); - if (isnan(rotation)) - rotation = 0; - avtext_print_integers(tfc, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1); - print_int("rotation", rotation); + print_displaymatrix(tfc, (const int32_t*)sd->data); } else if (sd->type == AV_FRAME_DATA_AFD && sd->size > 0) { print_int("active_format", *sd->data); } else if (sd->type == AV_FRAME_DATA_GOP_TIMECODE && sd->size >= 8) { @@ -1303,31 +1313,12 @@ static void print_frame_side_data(AVTextFormatContext *tfc, } avtext_print_section_footer(tfc); } else if (sd->type == AV_FRAME_DATA_MASTERING_DISPLAY_METADATA) { - AVMasteringDisplayMetadata *metadata = (AVMasteringDisplayMetadata *)sd->data; - - if (metadata->has_primaries) { - print_q("red_x", metadata->display_primaries[0][0], '/'); - print_q("red_y", metadata->display_primaries[0][1], '/'); - print_q("green_x", metadata->display_primaries[1][0], '/'); - print_q("green_y", metadata->display_primaries[1][1], '/'); - print_q("blue_x", metadata->display_primaries[2][0], '/'); - print_q("blue_y", metadata->display_primaries[2][1], '/'); - - print_q("white_point_x", metadata->white_point[0], '/'); - print_q("white_point_y", metadata->white_point[1], '/'); - } - - if (metadata->has_luminance) { - print_q("min_luminance", metadata->min_luminance, '/'); - print_q("max_luminance", metadata->max_luminance, '/'); - } + print_mastering_display_metadata(tfc, (AVMasteringDisplayMetadata *)sd->data); } else if (sd->type == AV_FRAME_DATA_DYNAMIC_HDR_PLUS) { AVDynamicHDRPlus *metadata = (AVDynamicHDRPlus *)sd->data; print_dynamic_hdr10_plus(tfc, metadata); } else if (sd->type == AV_FRAME_DATA_CONTENT_LIGHT_LEVEL) { - AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data; - print_int("max_content", metadata->MaxCLL); - print_int("max_average", metadata->MaxFALL); + print_context_light_level(tfc, (AVContentLightMetadata *)sd->data); } else if (sd->type == AV_FRAME_DATA_ICC_PROFILE) { const AVDictionaryEntry *tag = av_dict_get(sd->metadata, "name", NULL, AV_DICT_MATCH_CASE); if (tag) From git at videolan.org Mon Jun 2 01:58:34 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Sun, 01 Jun 2025 22:58:34 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?fftools/ffprobe=3A_Fix_indentation?= Message-ID: <20250601225835.2729A412A83@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Sun Jun 1 04:59:27 2025 +0200| [e3b03207451b375092fdd23ee5c4b5c7923e67f3] | committer: Andreas Rheinhardt fftools/ffprobe: Fix indentation Forgotten after d76b0c4a3530005ce59ec1dcaefcb8dd03c4e0ce. Reviewed-by: softworkz . Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=e3b03207451b375092fdd23ee5c4b5c7923e67f3 --- fftools/ffprobe.c | 184 +++++++++++++++++++++++++++--------------------------- 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 751fbf1771..1346ed33c5 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -966,98 +966,98 @@ static void print_pkt_side_data(AVTextFormatContext *tfc, const AVPacketSideData *sd, SectionID id_data) { - const char *name = av_packet_side_data_name(sd->type); - - avtext_print_section_header(tfc, sd, id_data); - print_str("side_data_type", name ? name : "unknown"); - if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9*4) { - print_displaymatrix(tfc, (const int32_t*)sd->data); - } else if (sd->type == AV_PKT_DATA_STEREO3D) { - const AVStereo3D *stereo = (AVStereo3D *)sd->data; - print_str("type", av_stereo3d_type_name(stereo->type)); - print_int("inverted", !!(stereo->flags & AV_STEREO3D_FLAG_INVERT)); - print_str("view", av_stereo3d_view_name(stereo->view)); - print_str("primary_eye", av_stereo3d_primary_eye_name(stereo->primary_eye)); - print_int("baseline", stereo->baseline); - print_q("horizontal_disparity_adjustment", stereo->horizontal_disparity_adjustment, '/'); - print_q("horizontal_field_of_view", stereo->horizontal_field_of_view, '/'); - } else if (sd->type == AV_PKT_DATA_SPHERICAL) { - const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data; - print_str("projection", av_spherical_projection_name(spherical->projection)); - if (spherical->projection == AV_SPHERICAL_CUBEMAP) { - print_int("padding", spherical->padding); - } else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) { - size_t l, t, r, b; - av_spherical_tile_bounds(spherical, par->width, par->height, - &l, &t, &r, &b); - print_int("bound_left", l); - print_int("bound_top", t); - print_int("bound_right", r); - print_int("bound_bottom", b); - } - - print_int("yaw", (double) spherical->yaw / (1 << 16)); - print_int("pitch", (double) spherical->pitch / (1 << 16)); - print_int("roll", (double) spherical->roll / (1 << 16)); - } else if (sd->type == AV_PKT_DATA_SKIP_SAMPLES && sd->size == 10) { - print_int("skip_samples", AV_RL32(sd->data)); - print_int("discard_padding", AV_RL32(sd->data + 4)); - print_int("skip_reason", AV_RL8(sd->data + 8)); - print_int("discard_reason", AV_RL8(sd->data + 9)); - } else if (sd->type == AV_PKT_DATA_MASTERING_DISPLAY_METADATA) { - print_mastering_display_metadata(tfc, (AVMasteringDisplayMetadata *)sd->data); - } else if (sd->type == AV_PKT_DATA_CONTENT_LIGHT_LEVEL) { - print_context_light_level(tfc, (AVContentLightMetadata *)sd->data); - } else if (sd->type == AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT) { - print_ambient_viewing_environment( - tfc, (const AVAmbientViewingEnvironment *)sd->data); - } else if (sd->type == AV_PKT_DATA_DYNAMIC_HDR10_PLUS) { - AVDynamicHDRPlus *metadata = (AVDynamicHDRPlus *)sd->data; - print_dynamic_hdr10_plus(tfc, metadata); - } else if (sd->type == AV_PKT_DATA_DOVI_CONF) { - AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *)sd->data; - const char *comp = "unknown"; - print_int("dv_version_major", dovi->dv_version_major); - print_int("dv_version_minor", dovi->dv_version_minor); - print_int("dv_profile", dovi->dv_profile); - print_int("dv_level", dovi->dv_level); - print_int("rpu_present_flag", dovi->rpu_present_flag); - print_int("el_present_flag", dovi->el_present_flag); - print_int("bl_present_flag", dovi->bl_present_flag); - print_int("dv_bl_signal_compatibility_id", dovi->dv_bl_signal_compatibility_id); - switch (dovi->dv_md_compression) - { - case AV_DOVI_COMPRESSION_NONE: comp = "none"; break; - case AV_DOVI_COMPRESSION_LIMITED: comp = "limited"; break; - case AV_DOVI_COMPRESSION_RESERVED: comp = "reserved"; break; - case AV_DOVI_COMPRESSION_EXTENDED: comp = "extended"; break; - } - print_str("dv_md_compression", comp); - } else if (sd->type == AV_PKT_DATA_AUDIO_SERVICE_TYPE) { - enum AVAudioServiceType *t = (enum AVAudioServiceType *)sd->data; - print_int("service_type", *t); - } else if (sd->type == AV_PKT_DATA_MPEGTS_STREAM_ID) { - print_int("id", *sd->data); - } else if (sd->type == AV_PKT_DATA_CPB_PROPERTIES) { - const AVCPBProperties *prop = (AVCPBProperties *)sd->data; - print_int("max_bitrate", prop->max_bitrate); - print_int("min_bitrate", prop->min_bitrate); - print_int("avg_bitrate", prop->avg_bitrate); - print_int("buffer_size", prop->buffer_size); - print_int("vbv_delay", prop->vbv_delay); - } else if (sd->type == AV_PKT_DATA_WEBVTT_IDENTIFIER || - sd->type == AV_PKT_DATA_WEBVTT_SETTINGS) { - if (do_show_data) - avtext_print_data(tfc, "data", sd->data, sd->size); - avtext_print_data_hash(tfc, "data_hash", sd->data, sd->size); - } else if (sd->type == AV_PKT_DATA_FRAME_CROPPING && sd->size >= sizeof(uint32_t) * 4) { - print_int("crop_top", AV_RL32(sd->data)); - print_int("crop_bottom", AV_RL32(sd->data + 4)); - print_int("crop_left", AV_RL32(sd->data + 8)); - print_int("crop_right", AV_RL32(sd->data + 12)); - } else if (sd->type == AV_PKT_DATA_AFD && sd->size > 0) { - print_int("active_format", *sd->data); - } + const char *name = av_packet_side_data_name(sd->type); + + avtext_print_section_header(tfc, sd, id_data); + print_str("side_data_type", name ? name : "unknown"); + if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9*4) { + print_displaymatrix(tfc, (const int32_t*)sd->data); + } else if (sd->type == AV_PKT_DATA_STEREO3D) { + const AVStereo3D *stereo = (AVStereo3D *)sd->data; + print_str("type", av_stereo3d_type_name(stereo->type)); + print_int("inverted", !!(stereo->flags & AV_STEREO3D_FLAG_INVERT)); + print_str("view", av_stereo3d_view_name(stereo->view)); + print_str("primary_eye", av_stereo3d_primary_eye_name(stereo->primary_eye)); + print_int("baseline", stereo->baseline); + print_q("horizontal_disparity_adjustment", stereo->horizontal_disparity_adjustment, '/'); + print_q("horizontal_field_of_view", stereo->horizontal_field_of_view, '/'); + } else if (sd->type == AV_PKT_DATA_SPHERICAL) { + const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data; + print_str("projection", av_spherical_projection_name(spherical->projection)); + if (spherical->projection == AV_SPHERICAL_CUBEMAP) { + print_int("padding", spherical->padding); + } else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) { + size_t l, t, r, b; + av_spherical_tile_bounds(spherical, par->width, par->height, + &l, &t, &r, &b); + print_int("bound_left", l); + print_int("bound_top", t); + print_int("bound_right", r); + print_int("bound_bottom", b); + } + + print_int("yaw", (double) spherical->yaw / (1 << 16)); + print_int("pitch", (double) spherical->pitch / (1 << 16)); + print_int("roll", (double) spherical->roll / (1 << 16)); + } else if (sd->type == AV_PKT_DATA_SKIP_SAMPLES && sd->size == 10) { + print_int("skip_samples", AV_RL32(sd->data)); + print_int("discard_padding", AV_RL32(sd->data + 4)); + print_int("skip_reason", AV_RL8(sd->data + 8)); + print_int("discard_reason", AV_RL8(sd->data + 9)); + } else if (sd->type == AV_PKT_DATA_MASTERING_DISPLAY_METADATA) { + print_mastering_display_metadata(tfc, (AVMasteringDisplayMetadata *)sd->data); + } else if (sd->type == AV_PKT_DATA_CONTENT_LIGHT_LEVEL) { + print_context_light_level(tfc, (AVContentLightMetadata *)sd->data); + } else if (sd->type == AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT) { + print_ambient_viewing_environment( + tfc, (const AVAmbientViewingEnvironment *)sd->data); + } else if (sd->type == AV_PKT_DATA_DYNAMIC_HDR10_PLUS) { + AVDynamicHDRPlus *metadata = (AVDynamicHDRPlus *)sd->data; + print_dynamic_hdr10_plus(tfc, metadata); + } else if (sd->type == AV_PKT_DATA_DOVI_CONF) { + AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *)sd->data; + const char *comp = "unknown"; + print_int("dv_version_major", dovi->dv_version_major); + print_int("dv_version_minor", dovi->dv_version_minor); + print_int("dv_profile", dovi->dv_profile); + print_int("dv_level", dovi->dv_level); + print_int("rpu_present_flag", dovi->rpu_present_flag); + print_int("el_present_flag", dovi->el_present_flag); + print_int("bl_present_flag", dovi->bl_present_flag); + print_int("dv_bl_signal_compatibility_id", dovi->dv_bl_signal_compatibility_id); + switch (dovi->dv_md_compression) + { + case AV_DOVI_COMPRESSION_NONE: comp = "none"; break; + case AV_DOVI_COMPRESSION_LIMITED: comp = "limited"; break; + case AV_DOVI_COMPRESSION_RESERVED: comp = "reserved"; break; + case AV_DOVI_COMPRESSION_EXTENDED: comp = "extended"; break; + } + print_str("dv_md_compression", comp); + } else if (sd->type == AV_PKT_DATA_AUDIO_SERVICE_TYPE) { + enum AVAudioServiceType *t = (enum AVAudioServiceType *)sd->data; + print_int("service_type", *t); + } else if (sd->type == AV_PKT_DATA_MPEGTS_STREAM_ID) { + print_int("id", *sd->data); + } else if (sd->type == AV_PKT_DATA_CPB_PROPERTIES) { + const AVCPBProperties *prop = (AVCPBProperties *)sd->data; + print_int("max_bitrate", prop->max_bitrate); + print_int("min_bitrate", prop->min_bitrate); + print_int("avg_bitrate", prop->avg_bitrate); + print_int("buffer_size", prop->buffer_size); + print_int("vbv_delay", prop->vbv_delay); + } else if (sd->type == AV_PKT_DATA_WEBVTT_IDENTIFIER || + sd->type == AV_PKT_DATA_WEBVTT_SETTINGS) { + if (do_show_data) + avtext_print_data(tfc, "data", sd->data, sd->size); + avtext_print_data_hash(tfc, "data_hash", sd->data, sd->size); + } else if (sd->type == AV_PKT_DATA_FRAME_CROPPING && sd->size >= sizeof(uint32_t) * 4) { + print_int("crop_top", AV_RL32(sd->data)); + print_int("crop_bottom", AV_RL32(sd->data + 4)); + print_int("crop_left", AV_RL32(sd->data + 8)); + print_int("crop_right", AV_RL32(sd->data + 12)); + } else if (sd->type == AV_PKT_DATA_AFD && sd->size > 0) { + print_int("active_format", *sd->data); + } } static void print_private_data(AVTextFormatContext *tfc, void *priv_data) From git at videolan.org Mon Jun 2 01:58:36 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Sun, 01 Jun 2025 22:58:36 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?fftools/graph/graphprint=3A_Remove_red?= =?utf-8?q?undant_avio=5Fflush=28=29?= Message-ID: <20250601225837.315F6412A75@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Sun Jun 1 05:14:23 2025 +0200| [688f3944cedf36963cf81fbd56e8022e89d038c3] | committer: Andreas Rheinhardt fftools/graph/graphprint: Remove redundant avio_flush() The AVIOContext will be automatically flushed upon closure. Reviewed-by: softworkz . Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=688f3944cedf36963cf81fbd56e8022e89d038c3 --- fftools/graph/graphprint.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fftools/graph/graphprint.c b/fftools/graph/graphprint.c index 7f0e85d008..e4c6886cf8 100644 --- a/fftools/graph/graphprint.c +++ b/fftools/graph/graphprint.c @@ -1070,7 +1070,6 @@ static int print_filtergraphs_priv(FilterGraph **graphs, int nb_graphs, InputFil } avio_write(avio, (const unsigned char *)target_buf.str, FFMIN(target_buf.len, target_buf.size - 1)); - avio_flush(avio); if ((ret = avio_closep(&avio)) < 0) av_log(NULL, AV_LOG_ERROR, "Error closing graph output file, loss of information possible: %s\n", av_err2str(ret)); From git at videolan.org Mon Jun 2 14:53:29 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Mon, 02 Jun 2025 11:53:29 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?tests/fate/mov=3A_Fix_fate-mov-mp4-fra?= =?utf-8?q?g-flush_requirements?= Message-ID: <20250602115330.619B3412A73@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Sun Jun 1 20:57:17 2025 +0200| [fa45e2002976632a38d5d44ef5c8a1966d4326ec] | committer: Andreas Rheinhardt tests/fate/mov: Fix fate-mov-mp4-frag-flush requirements Reviewed-by: Martin Storsj? Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=fa45e2002976632a38d5d44ef5c8a1966d4326ec --- tests/fate/mov.mak | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak index 6ab61e9f00..b966249dc0 100644 --- a/tests/fate/mov.mak +++ b/tests/fate/mov.mak @@ -87,7 +87,10 @@ fate-mov-frag-overlap: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/frag_overlap.mp4 fate-mov-mp4-frag-flush: CMD = md5 -f lavfi -i color=blue,format=rgb24,trim=duration=0.04 -f lavfi -i anullsrc,aformat=s16,atrim=duration=2 -c:v png -c:a pcm_s16le -movflags +empty_moov+hybrid_fragmented -frag_duration 1000000 -frag_interleave 1 -f mp4 fate-mov-mp4-frag-flush: CMP = oneline fate-mov-mp4-frag-flush: REF = a10c0e2e2dfc120f31ca5e59e0e4392a -FATE_MOV-$(call ALLYES, LAVFI_INDEV, COLOR_FILTER, FORMAT_FILTER, TRIM_FILTER, ANULL_FILTER, AFORMAT_FILTER, ATRIM_FILTER, PNG_ENCODER, PCM_S16LE_ENCODER, MOV_MUXER) += fate-mov-mp4-frag-flush +FATE_MOV_FFMPEG-$(call ALLYES, LAVFI_INDEV COLOR_FILTER FORMAT_FILTER TRIM_FILTER \ + ANULLSRC_FILTER AFORMAT_FILTER ATRIM_FILTER \ + WRAPPED_AVFRAME_DECODER PCM_S16LE_DECODER PCM_S16BE_DECODER \ + PNG_ENCODER PCM_S16LE_ENCODER MP4_MUXER) += fate-mov-mp4-frag-flush # Makes sure that we pick the right frames according to edit list when there is no keyframe with PTS < edit list start. # For example, when video starts on a B-frame, and edit list starts on that B-frame too. From git at videolan.org Mon Jun 2 14:53:31 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Mon, 02 Jun 2025 11:53:31 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?avcodec/ac3dec=3A_Hardcode_tables_to_s?= =?utf-8?q?ave_space?= Message-ID: <20250602115332.6CB83412A95@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Fri May 23 15:58:03 2025 +0200| [9416ffd8b87945e7803c33a7e4f14e404b58ff10] | committer: Andreas Rheinhardt avcodec/ac3dec: Hardcode tables to save space The code to initialize the ungrouped bap mantissa tables (bap 3 or 5) takes more bytes of .text than the tables itself; they have therefore been hardcoded. For GCC (14, -O3, albeit in an av_cold function), the initialization code takes 99B each for the fixed and floating point decoders (the code is currently duplicated), whereas the hardcoded tables only take 96B. For Clang 19 it were 374B each (I don't now what Clang was doing there). Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9416ffd8b87945e7803c33a7e4f14e404b58ff10 --- libavcodec/ac3dec.c | 16 ++-------------- libavcodec/ac3dec_data.c | 39 ++++++++++++++++++++++++++++++++++++++- libavcodec/ac3dec_data.h | 9 +++++++++ 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 49b170c235..dbe7f0b57c 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -55,9 +55,7 @@ static uint8_t ungroup_3_in_7_bits_tab[128][3]; /** tables for ungrouping mantissas */ static int b1_mantissas[32][3]; static int b2_mantissas[128][3]; -static int b3_mantissas[8]; static int b4_mantissas[128][2]; -static int b5_mantissas[16]; /** * Quantization table: levels for symmetric. bits for asymmetric. @@ -155,16 +153,6 @@ static av_cold void ac3_tables_init(void) b4_mantissas[i][0] = symmetric_dequant(i / 11, 11); b4_mantissas[i][1] = symmetric_dequant(i % 11, 11); } - /* generate ungrouped mantissa tables - reference: Tables 7.21 and 7.23 */ - for (i = 0; i < 7; i++) { - /* bap=3 mantissas */ - b3_mantissas[i] = symmetric_dequant(i, 7); - } - for (i = 0; i < 15; i++) { - /* bap=5 mantissas */ - b5_mantissas[i] = symmetric_dequant(i, 15); - } #if (!USE_FIXED) /* generate dynamic range table @@ -595,7 +583,7 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma } break; case 3: - mantissa = b3_mantissas[get_bits(gbc, 3)]; + mantissa = ff_ac3_bap3_mantissas[get_bits(gbc, 3)]; break; case 4: if (m->b4) { @@ -609,7 +597,7 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma } break; case 5: - mantissa = b5_mantissas[get_bits(gbc, 4)]; + mantissa = ff_ac3_bap5_mantissas[get_bits(gbc, 4)]; break; default: /* 6 to 15 */ /* Shift mantissa and sign-extend it. */ diff --git a/libavcodec/ac3dec_data.c b/libavcodec/ac3dec_data.c index a3794ab223..527b3353f2 100644 --- a/libavcodec/ac3dec_data.c +++ b/libavcodec/ac3dec_data.c @@ -21,7 +21,7 @@ /** * @file - * Tables taken directly from the AC-3 spec. + * Tables taken directly from the AC-3 spec or derived from it. */ #include "ac3dec_data.h" @@ -42,6 +42,43 @@ const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3] = { { 3, 0, 1 }, { 3, 0, 2 }, { 3, 1, 0 }, { 3, 1, 1 } }; +/** + * Ungrouped mantissa tables; the extra entry is padding to avoid range checks + */ +#define SYMMETRIC_DEQUANT(code, levels) (((code - (levels >> 1)) * (1 << 24)) / levels) +/** + * Table 7.21 + */ +const int ff_ac3_bap3_mantissas[7 + 1] = { + SYMMETRIC_DEQUANT(0, 7), + SYMMETRIC_DEQUANT(1, 7), + SYMMETRIC_DEQUANT(2, 7), + SYMMETRIC_DEQUANT(3, 7), + SYMMETRIC_DEQUANT(4, 7), + SYMMETRIC_DEQUANT(5, 7), + SYMMETRIC_DEQUANT(6, 7), +}; +/** + * Table 7.23 + */ +const int ff_ac3_bap5_mantissas[15 + 1] = { + SYMMETRIC_DEQUANT(0, 15), + SYMMETRIC_DEQUANT(1, 15), + SYMMETRIC_DEQUANT(2, 15), + SYMMETRIC_DEQUANT(3, 15), + SYMMETRIC_DEQUANT(4, 15), + SYMMETRIC_DEQUANT(5, 15), + SYMMETRIC_DEQUANT(6, 15), + SYMMETRIC_DEQUANT(7, 15), + SYMMETRIC_DEQUANT(8, 15), + SYMMETRIC_DEQUANT(9, 15), + SYMMETRIC_DEQUANT(10, 15), + SYMMETRIC_DEQUANT(11, 15), + SYMMETRIC_DEQUANT(12, 15), + SYMMETRIC_DEQUANT(13, 15), + SYMMETRIC_DEQUANT(14, 15), +}; + const uint8_t ff_eac3_hebap_tab[64] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, diff --git a/libavcodec/ac3dec_data.h b/libavcodec/ac3dec_data.h index 975b52ef2c..4f3a23f6c7 100644 --- a/libavcodec/ac3dec_data.h +++ b/libavcodec/ac3dec_data.h @@ -24,9 +24,18 @@ #include +#include "libavutil/attributes_internal.h" + +FF_VISIBILITY_PUSH_HIDDEN + extern const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3]; +extern const int ff_ac3_bap3_mantissas[ 7 + 1]; +extern const int ff_ac3_bap5_mantissas[15 + 1]; + extern const uint8_t ff_eac3_hebap_tab[64]; extern const uint8_t ff_eac3_default_spx_band_struct[17]; +FF_VISIBILITY_POP_HIDDEN + #endif /* AVCODEC_AC3DEC_DATA_H */ From git at videolan.org Mon Jun 2 14:53:33 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Mon, 02 Jun 2025 11:53:33 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?avcodec/ac3dec=3A_Deduplicate_mantissa?= =?utf-8?q?s_and_their_init_code?= Message-ID: <20250602115334.793DA412A97@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Sat May 24 18:39:26 2025 +0200| [20caa5cf2d912ebfc57c2b3335ad049d872abd7f] | committer: Andreas Rheinhardt avcodec/ac3dec: Deduplicate mantissas and their init code Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=20caa5cf2d912ebfc57c2b3335ad049d872abd7f --- libavcodec/ac3dec.c | 92 ++++++++++++------------------------------------ libavcodec/ac3dec_data.c | 60 ++++++++++++++++++++++++++++++- libavcodec/ac3dec_data.h | 8 +++++ 3 files changed, 90 insertions(+), 70 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index dbe7f0b57c..0e18403793 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -46,17 +46,6 @@ #include "decode.h" #include "kbdwin.h" -/** - * table for ungrouping 3 values in 7 bits. - * used for exponents and bap=2 mantissas - */ -static uint8_t ungroup_3_in_7_bits_tab[128][3]; - -/** tables for ungrouping mantissas */ -static int b1_mantissas[32][3]; -static int b2_mantissas[128][3]; -static int b4_mantissas[128][2]; - /** * Quantization table: levels for symmetric. bits for asymmetric. * reference: Table 7.18 Mapping of bap to Quantizer @@ -109,67 +98,28 @@ static const uint8_t ac3_default_coeffs[8][5][2] = { { { 2, 7 }, { 5, 5 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, }, }; -/** - * Symmetrical Dequantization - * reference: Section 7.3.3 Expansion of Mantissas for Symmetrical Quantization - * Tables 7.19 to 7.23 - */ -static inline int -symmetric_dequant(int code, int levels) -{ - return ((code - (levels >> 1)) * (1 << 24)) / levels; -} - +#if (!USE_FIXED) /* * Initialize tables at runtime. */ -static av_cold void ac3_tables_init(void) +static av_cold void ac3_float_tables_init(void) { - int i; - - /* generate table for ungrouping 3 values in 7 bits - reference: Section 7.1.3 Exponent Decoding */ - for (i = 0; i < 128; i++) { - ungroup_3_in_7_bits_tab[i][0] = i / 25; - ungroup_3_in_7_bits_tab[i][1] = (i % 25) / 5; - ungroup_3_in_7_bits_tab[i][2] = (i % 25) % 5; - } - - /* generate grouped mantissa tables - reference: Section 7.3.5 Ungrouping of Mantissas */ - for (i = 0; i < 32; i++) { - /* bap=1 mantissas */ - b1_mantissas[i][0] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][0], 3); - b1_mantissas[i][1] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][1], 3); - b1_mantissas[i][2] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][2], 3); - } - for (i = 0; i < 128; i++) { - /* bap=2 mantissas */ - b2_mantissas[i][0] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][0], 5); - b2_mantissas[i][1] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][1], 5); - b2_mantissas[i][2] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][2], 5); - - /* bap=4 mantissas */ - b4_mantissas[i][0] = symmetric_dequant(i / 11, 11); - b4_mantissas[i][1] = symmetric_dequant(i % 11, 11); - } - -#if (!USE_FIXED) /* generate dynamic range table reference: Section 7.7.1 Dynamic Range Control */ - for (i = 0; i < 256; i++) { + for (int i = 0; i < 256; i++) { int v = (i >> 5) - ((i >> 7) << 3) - 5; dynamic_range_tab[i] = powf(2.0f, v) * ((i & 0x1F) | 0x20); } /* generate compr dynamic range table reference: Section 7.7.2 Heavy Compression */ - for (i = 0; i < 256; i++) { + for (int i = 0; i < 256; i++) { int v = (i >> 4) - ((i >> 7) << 4) - 4; ff_ac3_heavy_dynamic_range_tab[i] = powf(2.0f, v) * ((i & 0xF) | 0x10); } -#endif + ff_ac3_init_static(); } +#endif static void ac3_downmix(AVCodecContext *avctx) { @@ -194,7 +144,6 @@ static void ac3_downmix(AVCodecContext *avctx) */ static av_cold int ac3_decode_init(AVCodecContext *avctx) { - static AVOnce init_static_once = AV_ONCE_INIT; AC3DecodeContext *s = avctx->priv_data; const float scale = 1.0f; int i, ret; @@ -235,7 +184,12 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) s->dlyptr[i] = s->delay[i]; } - ff_thread_once(&init_static_once, ac3_tables_init); +#if USE_FIXED + ff_ac3_init_static(); +#else + static AVOnce init_static_once = AV_ONCE_INIT; + ff_thread_once(&init_static_once, ac3_float_tables_init); +#endif return 0; } @@ -467,9 +421,9 @@ static int decode_exponents(AC3DecodeContext *s, av_log(s->avctx, AV_LOG_ERROR, "expacc %d is out-of-range\n", expacc); return AVERROR_INVALIDDATA; } - dexp[i++] = ungroup_3_in_7_bits_tab[expacc][0]; - dexp[i++] = ungroup_3_in_7_bits_tab[expacc][1]; - dexp[i++] = ungroup_3_in_7_bits_tab[expacc][2]; + dexp[i++] = ff_ac3_ungroup_3_in_7_bits_tab[expacc][0]; + dexp[i++] = ff_ac3_ungroup_3_in_7_bits_tab[expacc][1]; + dexp[i++] = ff_ac3_ungroup_3_in_7_bits_tab[expacc][2]; } /* convert to absolute exps and expand groups */ @@ -564,9 +518,9 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma mantissa = m->b1_mant[m->b1]; } else { int bits = get_bits(gbc, 5); - mantissa = b1_mantissas[bits][0]; - m->b1_mant[1] = b1_mantissas[bits][1]; - m->b1_mant[0] = b1_mantissas[bits][2]; + mantissa = ff_ac3_bap1_mantissas[bits][0]; + m->b1_mant[1] = ff_ac3_bap1_mantissas[bits][1]; + m->b1_mant[0] = ff_ac3_bap1_mantissas[bits][2]; m->b1 = 2; } break; @@ -576,9 +530,9 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma mantissa = m->b2_mant[m->b2]; } else { int bits = get_bits(gbc, 7); - mantissa = b2_mantissas[bits][0]; - m->b2_mant[1] = b2_mantissas[bits][1]; - m->b2_mant[0] = b2_mantissas[bits][2]; + mantissa = ff_ac3_bap2_mantissas[bits][0]; + m->b2_mant[1] = ff_ac3_bap2_mantissas[bits][1]; + m->b2_mant[0] = ff_ac3_bap2_mantissas[bits][2]; m->b2 = 2; } break; @@ -591,8 +545,8 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma mantissa = m->b4_mant; } else { int bits = get_bits(gbc, 7); - mantissa = b4_mantissas[bits][0]; - m->b4_mant = b4_mantissas[bits][1]; + mantissa = ff_ac3_bap4_mantissas[bits][0]; + m->b4_mant = ff_ac3_bap4_mantissas[bits][1]; m->b4 = 1; } break; diff --git a/libavcodec/ac3dec_data.c b/libavcodec/ac3dec_data.c index 527b3353f2..7ef64f1f84 100644 --- a/libavcodec/ac3dec_data.c +++ b/libavcodec/ac3dec_data.c @@ -25,6 +25,7 @@ */ #include "ac3dec_data.h" +#include "libavutil/thread.h" /** * Table used to ungroup 3 values stored in 5 bits. @@ -43,9 +44,20 @@ const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3] = { }; /** - * Ungrouped mantissa tables; the extra entry is padding to avoid range checks + * table for ungrouping 3 values in 7 bits. + * used for exponents and bap=2 mantissas + */ +uint8_t ff_ac3_ungroup_3_in_7_bits_tab[128][3]; + +/** + * Symmetrical Dequantization + * reference: Section 7.3.3 Expansion of Mantissas for Symmetrical Quantization + * Tables 7.19 to 7.23 */ #define SYMMETRIC_DEQUANT(code, levels) (((code - (levels >> 1)) * (1 << 24)) / levels) +/** + * Ungrouped mantissa tables; the extra entry is padding to avoid range checks + */ /** * Table 7.21 */ @@ -79,6 +91,52 @@ const int ff_ac3_bap5_mantissas[15 + 1] = { SYMMETRIC_DEQUANT(14, 15), }; +int ff_ac3_bap1_mantissas[32][3]; +int ff_ac3_bap2_mantissas[128][3]; +int ff_ac3_bap4_mantissas[128][2]; + +static inline int +symmetric_dequant(int code, int levels) +{ + return SYMMETRIC_DEQUANT(code, levels); +} + +static av_cold void ac3_init_static(void) +{ + /* generate table for ungrouping 3 values in 7 bits + reference: Section 7.1.3 Exponent Decoding */ + for (int i = 0; i < 128; ++i) { + ff_ac3_ungroup_3_in_7_bits_tab[i][0] = i / 25; + ff_ac3_ungroup_3_in_7_bits_tab[i][1] = (i % 25) / 5; + ff_ac3_ungroup_3_in_7_bits_tab[i][2] = (i % 25) % 5; + } + + /* generate grouped mantissa tables + reference: Section 7.3.5 Ungrouping of Mantissas */ + for (int i = 0; i < 32; ++i) { + /* bap=1 mantissas */ + ff_ac3_bap1_mantissas[i][0] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][0], 3); + ff_ac3_bap1_mantissas[i][1] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][1], 3); + ff_ac3_bap1_mantissas[i][2] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][2], 3); + } + for (int i = 0; i < 128; ++i) { + /* bap=2 mantissas */ + ff_ac3_bap2_mantissas[i][0] = symmetric_dequant(ff_ac3_ungroup_3_in_7_bits_tab[i][0], 5); + ff_ac3_bap2_mantissas[i][1] = symmetric_dequant(ff_ac3_ungroup_3_in_7_bits_tab[i][1], 5); + ff_ac3_bap2_mantissas[i][2] = symmetric_dequant(ff_ac3_ungroup_3_in_7_bits_tab[i][2], 5); + + /* bap=4 mantissas */ + ff_ac3_bap4_mantissas[i][0] = symmetric_dequant(i / 11, 11); + ff_ac3_bap4_mantissas[i][1] = symmetric_dequant(i % 11, 11); + } +} + +av_cold void ff_ac3_init_static(void) +{ + static AVOnce ac3_init_static_once = AV_ONCE_INIT; + ff_thread_once(&ac3_init_static_once, ac3_init_static); +} + const uint8_t ff_eac3_hebap_tab[64] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, diff --git a/libavcodec/ac3dec_data.h b/libavcodec/ac3dec_data.h index 4f3a23f6c7..1bbfa8b71e 100644 --- a/libavcodec/ac3dec_data.h +++ b/libavcodec/ac3dec_data.h @@ -29,13 +29,21 @@ FF_VISIBILITY_PUSH_HIDDEN extern const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3]; +extern uint8_t ff_ac3_ungroup_3_in_7_bits_tab[128][3]; extern const int ff_ac3_bap3_mantissas[ 7 + 1]; extern const int ff_ac3_bap5_mantissas[15 + 1]; +/** tables for ungrouping mantissas */ +extern int ff_ac3_bap1_mantissas[32][3]; +extern int ff_ac3_bap2_mantissas[128][3]; +extern int ff_ac3_bap4_mantissas[128][2]; + extern const uint8_t ff_eac3_hebap_tab[64]; extern const uint8_t ff_eac3_default_spx_band_struct[17]; +void ff_ac3_init_static(void); + FF_VISIBILITY_POP_HIDDEN #endif /* AVCODEC_AC3DEC_DATA_H */ From git at videolan.org Mon Jun 2 14:53:36 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Mon, 02 Jun 2025 11:53:36 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?avcodec/ac3=3A_Move_gain_value_defines?= =?utf-8?q?_to_ac3defs=2Eh?= Message-ID: <20250602115337.A48C6412A9F@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Sat May 24 18:41:17 2025 +0200| [11723b3526e05719e10ee0ce53c534c741e759de] | committer: Andreas Rheinhardt avcodec/ac3: Move gain value defines to ac3defs.h Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=11723b3526e05719e10ee0ce53c534c741e759de --- libavcodec/ac3.h | 11 ----------- libavcodec/ac3defs.h | 11 +++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libavcodec/ac3.h b/libavcodec/ac3.h index 2386c15ad0..ccd437f700 100644 --- a/libavcodec/ac3.h +++ b/libavcodec/ac3.h @@ -81,17 +81,6 @@ typedef float SHORTFLOAT; #define AC3_LEVEL(x) ROUND15((x) * FIXR15(M_SQRT1_2)) -/* pre-defined gain values */ -#define LEVEL_PLUS_3DB M_SQRT2 -#define LEVEL_PLUS_1POINT5DB 1.1892071150027209 -#define LEVEL_MINUS_1POINT5DB 0.8408964152537145 -#define LEVEL_MINUS_3DB M_SQRT1_2 -#define LEVEL_MINUS_4POINT5DB 0.5946035575013605 -#define LEVEL_MINUS_6DB 0.5000000000000000 -#define LEVEL_MINUS_9DB 0.3535533905932738 -#define LEVEL_ZERO 0.0000000000000000 -#define LEVEL_ONE 1.0000000000000000 - typedef struct AC3BitAllocParameters { int sr_code; int sr_shift; diff --git a/libavcodec/ac3defs.h b/libavcodec/ac3defs.h index ff92f0ac4a..f9b1be059f 100644 --- a/libavcodec/ac3defs.h +++ b/libavcodec/ac3defs.h @@ -34,6 +34,17 @@ #define AC3_CRITICAL_BANDS 50 #define AC3_MAX_CPL_BANDS 18 +/* pre-defined gain values */ +#define LEVEL_PLUS_3DB M_SQRT2 +#define LEVEL_PLUS_1POINT5DB 1.1892071150027209 +#define LEVEL_MINUS_1POINT5DB 0.8408964152537145 +#define LEVEL_MINUS_3DB M_SQRT1_2 +#define LEVEL_MINUS_4POINT5DB 0.5946035575013605 +#define LEVEL_MINUS_6DB 0.5000000000000000 +#define LEVEL_MINUS_9DB 0.3535533905932738 +#define LEVEL_ZERO 0.0000000000000000 +#define LEVEL_ONE 1.0000000000000000 + /* exponent encoding strategy */ #define EXP_REUSE 0 #define EXP_NEW 1 From git at videolan.org Mon Jun 2 14:53:38 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Mon, 02 Jun 2025 11:53:38 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?avcodec/ac3=7Bdec=2Cenc=7D=3A_Deduplic?= =?utf-8?q?ate_gain_levels_table?= Message-ID: <20250602115339.B1B5B412A73@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Sat May 24 18:58:24 2025 +0200| [dbd2ca3580fa90ff6d7bf226e9a487f12a2ca3a3] | committer: Andreas Rheinhardt avcodec/ac3{dec,enc}: Deduplicate gain levels table (I don't know why the encoder only uses eight of the nine values.) Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=dbd2ca3580fa90ff6d7bf226e9a487f12a2ca3a3 --- libavcodec/ac3dec.c | 36 ++++++++++++------------------------ libavcodec/ac3enc.c | 5 +---- libavcodec/ac3tab.c | 14 ++++++++++++++ libavcodec/ac3tab.h | 5 +++++ 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 0e18403793..2b87c7a5f9 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -61,18 +61,6 @@ static float dynamic_range_tab[256]; float ff_ac3_heavy_dynamic_range_tab[256]; #endif -/** Adjustments in dB gain */ -static const float gain_levels[9] = { - LEVEL_PLUS_3DB, - LEVEL_PLUS_1POINT5DB, - LEVEL_ONE, - LEVEL_MINUS_1POINT5DB, - LEVEL_MINUS_3DB, - LEVEL_MINUS_4POINT5DB, - LEVEL_MINUS_6DB, - LEVEL_ZERO, - LEVEL_MINUS_9DB -}; /** Adjustments in dB gain (LFE, +10 to -21 dB) */ static const float gain_levels_lfe[32] = { @@ -346,8 +334,8 @@ static int parse_frame_header(AC3DecodeContext *s) static int set_downmix_coeffs(AC3DecodeContext *s) { int i; - float cmix = gain_levels[s-> center_mix_level]; - float smix = gain_levels[s->surround_mix_level]; + float cmix = ff_ac3_gain_levels[s-> center_mix_level]; + float smix = ff_ac3_gain_levels[s->surround_mix_level]; float norm0, norm1; float downmix_coeffs[2][AC3_MAX_CHANNELS]; @@ -360,8 +348,8 @@ static int set_downmix_coeffs(AC3DecodeContext *s) } for (i = 0; i < s->fbw_channels; i++) { - downmix_coeffs[0][i] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]]; - downmix_coeffs[1][i] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]]; + downmix_coeffs[0][i] = ff_ac3_gain_levels[ac3_default_coeffs[s->channel_mode][i][0]]; + downmix_coeffs[1][i] = ff_ac3_gain_levels[ac3_default_coeffs[s->channel_mode][i][1]]; } if (s->channel_mode > 1 && s->channel_mode & 1) { downmix_coeffs[0][1] = downmix_coeffs[1][1] = cmix; @@ -1562,10 +1550,10 @@ dependent_frame: s->output_mode = AC3_CHMODE_STEREO; } - s->loro_center_mix_level = gain_levels[s-> center_mix_level]; - s->loro_surround_mix_level = gain_levels[s->surround_mix_level]; - s->ltrt_center_mix_level = gain_levels[s-> center_mix_level_ltrt]; - s->ltrt_surround_mix_level = gain_levels[s->surround_mix_level_ltrt]; + s->loro_center_mix_level = ff_ac3_gain_levels[s-> center_mix_level]; + s->loro_surround_mix_level = ff_ac3_gain_levels[s->surround_mix_level]; + s->ltrt_center_mix_level = ff_ac3_gain_levels[s-> center_mix_level_ltrt]; + s->ltrt_surround_mix_level = ff_ac3_gain_levels[s->surround_mix_level_ltrt]; switch (s->preferred_downmix) { case AC3_DMIXMOD_LTRT: s->preferred_stereo_downmix = AV_DOWNMIX_TYPE_LTRT; @@ -1804,10 +1792,10 @@ skip: downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_UNKNOWN; break; } - downmix_info->center_mix_level = gain_levels[s-> center_mix_level]; - downmix_info->center_mix_level_ltrt = gain_levels[s-> center_mix_level_ltrt]; - downmix_info->surround_mix_level = gain_levels[s-> surround_mix_level]; - downmix_info->surround_mix_level_ltrt = gain_levels[s->surround_mix_level_ltrt]; + downmix_info->center_mix_level = ff_ac3_gain_levels[s-> center_mix_level]; + downmix_info->center_mix_level_ltrt = ff_ac3_gain_levels[s-> center_mix_level_ltrt]; + downmix_info->surround_mix_level = ff_ac3_gain_levels[s-> surround_mix_level]; + downmix_info->surround_mix_level_ltrt = ff_ac3_gain_levels[s->surround_mix_level_ltrt]; if (s->lfe_mix_level_exists) downmix_info->lfe_mix_level = gain_levels_lfe[s->lfe_mix_level]; else diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index a1783577c5..a316d4e4d7 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -71,10 +71,7 @@ static const float surmixlev_options[SURMIXLEV_NUM_OPTIONS] = { }; #define EXTMIXLEV_NUM_OPTIONS 8 -static const float extmixlev_options[EXTMIXLEV_NUM_OPTIONS] = { - LEVEL_PLUS_3DB, LEVEL_PLUS_1POINT5DB, LEVEL_ONE, LEVEL_MINUS_1POINT5DB, - LEVEL_MINUS_3DB, LEVEL_MINUS_4POINT5DB, LEVEL_MINUS_6DB, LEVEL_ZERO -}; +#define extmixlev_options ff_ac3_gain_levels /* The first two options apply only to the AC-3 encoders; * the rest is also valid for EAC-3. When modifying it, diff --git a/libavcodec/ac3tab.c b/libavcodec/ac3tab.c index 48c89a8ba0..b38e7237b3 100644 --- a/libavcodec/ac3tab.c +++ b/libavcodec/ac3tab.c @@ -25,6 +25,7 @@ */ #include "libavutil/channel_layout.h" +#include "libavutil/mathematics.h" #include "ac3tab.h" @@ -147,6 +148,19 @@ const uint16_t ff_ac3_fast_gain_tab[8]= { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400, }; +/** Adjustments in dB gain */ +const float ff_ac3_gain_levels[9] = { + LEVEL_PLUS_3DB, + LEVEL_PLUS_1POINT5DB, + LEVEL_ONE, + LEVEL_MINUS_1POINT5DB, + LEVEL_MINUS_3DB, + LEVEL_MINUS_4POINT5DB, + LEVEL_MINUS_6DB, + LEVEL_ZERO, + LEVEL_MINUS_9DB +}; + const uint64_t ff_eac3_custom_channel_map_locations[16][2] = { { 1, AV_CH_FRONT_LEFT }, { 1, AV_CH_FRONT_CENTER }, diff --git a/libavcodec/ac3tab.h b/libavcodec/ac3tab.h index dcef643acb..3f83ce7b8c 100644 --- a/libavcodec/ac3tab.h +++ b/libavcodec/ac3tab.h @@ -26,6 +26,9 @@ #include "ac3defs.h" +#include "libavutil/attributes_internal.h" + +FF_VISIBILITY_PUSH_HIDDEN extern const uint16_t ff_ac3_frame_size_tab[38][3]; extern const uint8_t ff_ac3_channels_tab[8]; extern const uint16_t ff_ac3_channel_layout_tab[8]; @@ -43,7 +46,9 @@ extern const int16_t ff_ac3_floor_tab[8]; extern const uint16_t ff_ac3_fast_gain_tab[8]; extern const uint8_t ff_ac3_band_start_tab[AC3_CRITICAL_BANDS+1]; extern const uint8_t ff_ac3_bin_to_band_tab[253]; +extern const float ff_ac3_gain_levels[9]; extern const uint64_t ff_eac3_custom_channel_map_locations[16][2]; +FF_VISIBILITY_POP_HIDDEN #define COMMON_CHANNEL_MAP \ { { 0, 1, }, { 0, 1, 2, } },\ From git at videolan.org Mon Jun 2 14:53:40 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Mon, 02 Jun 2025 11:53:40 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?avcodec/ac3dec=3A_Deduplicate_tables?= Message-ID: <20250602115341.BE1FD412A95@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Fri May 30 00:20:15 2025 +0200| [2d5f5e8726b7cf2d4114a64f479f42f42dad9861] | committer: Andreas Rheinhardt avcodec/ac3dec: Deduplicate tables Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2d5f5e8726b7cf2d4114a64f479f42f42dad9861 --- libavcodec/ac3dec.c | 44 ++++---------------------------------------- libavcodec/ac3dec_data.c | 33 +++++++++++++++++++++++++++++++++ libavcodec/ac3dec_data.h | 5 +++++ 3 files changed, 42 insertions(+), 40 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 2b87c7a5f9..5eacab4475 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -46,47 +46,11 @@ #include "decode.h" #include "kbdwin.h" -/** - * Quantization table: levels for symmetric. bits for asymmetric. - * reference: Table 7.18 Mapping of bap to Quantizer - */ -static const uint8_t quantization_tab[16] = { - 0, 3, 5, 7, 11, 15, - 5, 6, 7, 8, 9, 10, 11, 12, 14, 16 -}; - #if (!USE_FIXED) /** dynamic range table. converts codes to scale factors. */ static float dynamic_range_tab[256]; float ff_ac3_heavy_dynamic_range_tab[256]; -#endif - - -/** Adjustments in dB gain (LFE, +10 to -21 dB) */ -static const float gain_levels_lfe[32] = { - 3.162275, 2.818382, 2.511886, 2.238719, 1.995261, 1.778278, 1.584893, - 1.412536, 1.258924, 1.122018, 1.000000, 0.891251, 0.794328, 0.707946, - 0.630957, 0.562341, 0.501187, 0.446683, 0.398107, 0.354813, 0.316227, - 0.281838, 0.251188, 0.223872, 0.199526, 0.177828, 0.158489, 0.141253, - 0.125892, 0.112201, 0.100000, 0.089125 -}; -/** - * Table for default stereo downmixing coefficients - * reference: Section 7.8.2 Downmixing Into Two Channels - */ -static const uint8_t ac3_default_coeffs[8][5][2] = { - { { 2, 7 }, { 7, 2 }, }, - { { 4, 4 }, }, - { { 2, 7 }, { 7, 2 }, }, - { { 2, 7 }, { 5, 5 }, { 7, 2 }, }, - { { 2, 7 }, { 7, 2 }, { 6, 6 }, }, - { { 2, 7 }, { 5, 5 }, { 7, 2 }, { 8, 8 }, }, - { { 2, 7 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, }, - { { 2, 7 }, { 5, 5 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, }, -}; - -#if (!USE_FIXED) /* * Initialize tables at runtime. */ @@ -348,8 +312,8 @@ static int set_downmix_coeffs(AC3DecodeContext *s) } for (i = 0; i < s->fbw_channels; i++) { - downmix_coeffs[0][i] = ff_ac3_gain_levels[ac3_default_coeffs[s->channel_mode][i][0]]; - downmix_coeffs[1][i] = ff_ac3_gain_levels[ac3_default_coeffs[s->channel_mode][i][1]]; + downmix_coeffs[0][i] = ff_ac3_gain_levels[ff_ac3_default_coeffs[s->channel_mode][i][0]]; + downmix_coeffs[1][i] = ff_ac3_gain_levels[ff_ac3_default_coeffs[s->channel_mode][i][1]]; } if (s->channel_mode > 1 && s->channel_mode & 1) { downmix_coeffs[0][1] = downmix_coeffs[1][1] = cmix; @@ -547,7 +511,7 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma av_log(s->avctx, AV_LOG_ERROR, "bap %d is invalid in plain AC-3\n", bap); bap = 15; } - mantissa = (unsigned)get_sbits(gbc, quantization_tab[bap]) << (24 - quantization_tab[bap]); + mantissa = (unsigned)get_sbits(gbc, ff_ac3_quantization_tab[bap]) << (24 - ff_ac3_quantization_tab[bap]); break; } coeffs[freq] = mantissa >> exps[freq]; @@ -1797,7 +1761,7 @@ skip: downmix_info->surround_mix_level = ff_ac3_gain_levels[s-> surround_mix_level]; downmix_info->surround_mix_level_ltrt = ff_ac3_gain_levels[s->surround_mix_level_ltrt]; if (s->lfe_mix_level_exists) - downmix_info->lfe_mix_level = gain_levels_lfe[s->lfe_mix_level]; + downmix_info->lfe_mix_level = ff_eac3_gain_levels_lfe[s->lfe_mix_level]; else downmix_info->lfe_mix_level = 0.0; // -inf dB } diff --git a/libavcodec/ac3dec_data.c b/libavcodec/ac3dec_data.c index 7ef64f1f84..0f5402c335 100644 --- a/libavcodec/ac3dec_data.c +++ b/libavcodec/ac3dec_data.c @@ -137,6 +137,30 @@ av_cold void ff_ac3_init_static(void) ff_thread_once(&ac3_init_static_once, ac3_init_static); } +/** + * Quantization table: levels for symmetric. bits for asymmetric. + * reference: Table 7.18 Mapping of bap to Quantizer + */ +const uint8_t ff_ac3_quantization_tab[16] = { + 0, 3, 5, 7, 11, 15, + 5, 6, 7, 8, 9, 10, 11, 12, 14, 16 +}; + +/** + * Table for default stereo downmixing coefficients + * reference: Section 7.8.2 Downmixing Into Two Channels + */ +const uint8_t ff_ac3_default_coeffs[8][5][2] = { + { { 2, 7 }, { 7, 2 }, }, + { { 4, 4 }, }, + { { 2, 7 }, { 7, 2 }, }, + { { 2, 7 }, { 5, 5 }, { 7, 2 }, }, + { { 2, 7 }, { 7, 2 }, { 6, 6 }, }, + { { 2, 7 }, { 5, 5 }, { 7, 2 }, { 8, 8 }, }, + { { 2, 7 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, }, + { { 2, 7 }, { 5, 5 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, }, +}; + const uint8_t ff_eac3_hebap_tab[64] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, @@ -152,3 +176,12 @@ const uint8_t ff_eac3_hebap_tab[64] = { */ const uint8_t ff_eac3_default_spx_band_struct[17] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }; + +/** Adjustments in dB gain (LFE, +10 to -21 dB) */ +const float ff_eac3_gain_levels_lfe[32] = { + 3.162275, 2.818382, 2.511886, 2.238719, 1.995261, 1.778278, 1.584893, + 1.412536, 1.258924, 1.122018, 1.000000, 0.891251, 0.794328, 0.707946, + 0.630957, 0.562341, 0.501187, 0.446683, 0.398107, 0.354813, 0.316227, + 0.281838, 0.251188, 0.223872, 0.199526, 0.177828, 0.158489, 0.141253, + 0.125892, 0.112201, 0.100000, 0.089125 +}; diff --git a/libavcodec/ac3dec_data.h b/libavcodec/ac3dec_data.h index 1bbfa8b71e..613871627b 100644 --- a/libavcodec/ac3dec_data.h +++ b/libavcodec/ac3dec_data.h @@ -39,8 +39,13 @@ extern int ff_ac3_bap1_mantissas[32][3]; extern int ff_ac3_bap2_mantissas[128][3]; extern int ff_ac3_bap4_mantissas[128][2]; +extern const uint8_t ff_ac3_quantization_tab[16]; + +extern const uint8_t ff_ac3_default_coeffs[8][5][2]; + extern const uint8_t ff_eac3_hebap_tab[64]; extern const uint8_t ff_eac3_default_spx_band_struct[17]; +extern const float ff_eac3_gain_levels_lfe[32]; void ff_ac3_init_static(void); From git at videolan.org Mon Jun 2 14:53:42 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Mon, 02 Jun 2025 11:53:42 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?avcodec/hpeldsp=3A_Remove_duplicate_pe?= =?utf-8?q?l_functions?= Message-ID: <20250602115343.CF9F6412A71@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Fri May 30 12:40:16 2025 +0200| [6d45668801db9cd22b15e9d947738b25346a691f] | committer: Andreas Rheinhardt avcodec/hpeldsp: Remove duplicate pel functions Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=6d45668801db9cd22b15e9d947738b25346a691f --- libavcodec/hpeldsp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libavcodec/hpeldsp.c b/libavcodec/hpeldsp.c index 80494c9749..db0e02ee93 100644 --- a/libavcodec/hpeldsp.c +++ b/libavcodec/hpeldsp.c @@ -314,9 +314,6 @@ CALL_2X_PIXELS(OPNAME ## _pixels16_y2_8_c, \ CALL_2X_PIXELS(OPNAME ## _pixels16_xy2_8_c, \ OPNAME ## _pixels8_xy2_8_c, \ 8) \ -CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_8_c, \ - OPNAME ## _pixels8_8_c, \ - 8) \ CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_x2_8_c, \ OPNAME ## _no_rnd_pixels8_x2_8_c, \ 8) \ @@ -330,6 +327,8 @@ CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_xy2_8_c, \ #define op_avg(a, b) a = rnd_avg32(a, b) #define op_put(a, b) a = b #define put_no_rnd_pixels8_8_c put_pixels8_8_c +#define put_no_rnd_pixels16_8_c put_pixels16_8_c +#define avg_no_rnd_pixels16_8_c avg_pixels16_8_c PIXOP2(avg, op_avg) PIXOP2(put, op_put) #undef op_avg From git at videolan.org Mon Jun 2 14:53:44 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Mon, 02 Jun 2025 11:53:44 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?avcodec/x86/hpeldsp=5Finit=3A_Use_ff?= =?utf-8?q?=5Favg=5Fpixels16=5Fmmxext?= Message-ID: <20250602115345.DB8BB412A97@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Fri May 30 12:55:54 2025 +0200| [83b34691429729fea2c78bf419622ceb4a7810b2] | committer: Andreas Rheinhardt avcodec/x86/hpeldsp_init: Use ff_avg_pixels16_mmxext avg_pixels_tab[0][0] does the same as avg_no_rnd_pixels_tab[0]. Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=83b34691429729fea2c78bf419622ceb4a7810b2 --- libavcodec/x86/hpeldsp_init.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/x86/hpeldsp_init.c b/libavcodec/x86/hpeldsp_init.c index 4a0513d06d..12edcd9e83 100644 --- a/libavcodec/x86/hpeldsp_init.c +++ b/libavcodec/x86/hpeldsp_init.c @@ -122,7 +122,6 @@ CALL_2X_PIXELS(put_pixels16_xy2_mmx, ff_put_pixels8_xy2_mmx, 8) CALL_2X_PIXELS(put_no_rnd_pixels16_x2 ## CPUEXT, ff_put_no_rnd_pixels8_x2 ## CPUEXT, 8) \ CALL_2X_PIXELS(put_pixels16_y2 ## CPUEXT, ff_put_pixels8_y2 ## CPUEXT, 8) \ CALL_2X_PIXELS(put_no_rnd_pixels16_y2 ## CPUEXT, ff_put_no_rnd_pixels8_y2 ## CPUEXT, 8) \ - CALL_2X_PIXELS(avg_pixels16 ## CPUEXT, ff_avg_pixels8 ## CPUEXT, 8) \ CALL_2X_PIXELS(avg_pixels16_x2 ## CPUEXT, ff_avg_pixels8_x2 ## CPUEXT, 8) \ CALL_2X_PIXELS(avg_pixels16_y2 ## CPUEXT, ff_avg_pixels8_y2 ## CPUEXT, 8) \ CALL_2X_PIXELS(avg_pixels16_xy2 ## CPUEXT, ff_avg_pixels8_xy2 ## CPUEXT, 8) \ @@ -170,7 +169,7 @@ static void hpeldsp_init_mmxext(HpelDSPContext *c, int flags) c->put_pixels_tab[0][1] = ff_put_pixels16_x2_mmxext; c->put_pixels_tab[0][2] = put_pixels16_y2_mmxext; - c->avg_pixels_tab[0][0] = avg_pixels16_mmxext; + c->avg_pixels_tab[0][0] = ff_avg_pixels16_mmxext; c->avg_pixels_tab[0][1] = avg_pixels16_x2_mmxext; c->avg_pixels_tab[0][2] = avg_pixels16_y2_mmxext; c->avg_pixels_tab[0][3] = avg_pixels16_xy2_mmxext; From git at videolan.org Mon Jun 2 14:53:46 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Mon, 02 Jun 2025 11:53:46 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?avcodec/hpeldsp=5Finit=3A_Detemplatize?= Message-ID: <20250602115347.E79F5412A73@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Fri May 30 13:54:50 2025 +0200| [09aeeeb66323792577ffbc7faed82c1a3180553f] | committer: Andreas Rheinhardt avcodec/hpeldsp_init: Detemplatize Since a51279bbdea0d6db920d71980262bccd0ce78226, hpeldsp_rnd_template.c was only included once and one of the two functions in rnd_template.c was only enabled once. Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=09aeeeb66323792577ffbc7faed82c1a3180553f --- libavcodec/x86/hpeldsp_init.c | 258 +++++++++++++++++++++++++++++++++- libavcodec/x86/hpeldsp_rnd_template.c | 202 -------------------------- libavcodec/x86/rnd_template.c | 79 ----------- 3 files changed, 252 insertions(+), 287 deletions(-) diff --git a/libavcodec/x86/hpeldsp_init.c b/libavcodec/x86/hpeldsp_init.c index 12edcd9e83..6b2ad4494b 100644 --- a/libavcodec/x86/hpeldsp_init.c +++ b/libavcodec/x86/hpeldsp_init.c @@ -22,6 +22,9 @@ * MMX optimization by Nick Kurshev */ +#include +#include + #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/x86/cpu.h" @@ -74,19 +77,263 @@ void ff_avg_approx_pixels8_xy2_mmxext(uint8_t *block, const uint8_t *pixels, /* MMX no rounding */ #define DEF(x, y) x ## _no_rnd_ ## y ## _mmx #define SET_RND MOVQ_WONE -#define PAVGBP(a, b, c, d, e, f) PAVGBP_MMX_NO_RND(a, b, c, d, e, f) -#define PAVGB(a, b, c, e) PAVGB_MMX_NO_RND(a, b, c, e) #define STATIC static #include "rnd_template.c" -#include "hpeldsp_rnd_template.c" #undef DEF #undef SET_RND -#undef PAVGBP -#undef PAVGB #undef STATIC +// this routine is 'slightly' suboptimal but mostly unused +static void avg_no_rnd_pixels8_xy2_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h) +{ + MOVQ_ZERO(mm7); + MOVQ_WONE(mm6); // =2 for rnd and =1 for no_rnd version + __asm__ volatile( + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm4 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddusw %%mm0, %%mm4 \n\t" + "paddusw %%mm1, %%mm5 \n\t" + "xor %%"FF_REG_a", %%"FF_REG_a" \n\t" + "add %3, %1 \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1, %%"FF_REG_a"), %%mm0 \n\t" + "movq 1(%1, %%"FF_REG_a"), %%mm2 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm2, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddusw %%mm2, %%mm0 \n\t" + "paddusw %%mm3, %%mm1 \n\t" + "paddusw %%mm6, %%mm4 \n\t" + "paddusw %%mm6, %%mm5 \n\t" + "paddusw %%mm0, %%mm4 \n\t" + "paddusw %%mm1, %%mm5 \n\t" + "psrlw $2, %%mm4 \n\t" + "psrlw $2, %%mm5 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm3 \n\t" + "packuswb %%mm5, %%mm4 \n\t" + "pcmpeqd %%mm2, %%mm2 \n\t" + "paddb %%mm2, %%mm2 \n\t" + PAVGB_MMX(%%mm3, %%mm4, %%mm5, %%mm2) + "movq %%mm5, (%2, %%"FF_REG_a") \n\t" + "add %3, %%"FF_REG_a" \n\t" + + "movq (%1, %%"FF_REG_a"), %%mm2 \n\t" // 0 <-> 2 1 <-> 3 + "movq 1(%1, %%"FF_REG_a"), %%mm4 \n\t" + "movq %%mm2, %%mm3 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddusw %%mm2, %%mm4 \n\t" + "paddusw %%mm3, %%mm5 \n\t" + "paddusw %%mm6, %%mm0 \n\t" + "paddusw %%mm6, %%mm1 \n\t" + "paddusw %%mm4, %%mm0 \n\t" + "paddusw %%mm5, %%mm1 \n\t" + "psrlw $2, %%mm0 \n\t" + "psrlw $2, %%mm1 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm3 \n\t" + "packuswb %%mm1, %%mm0 \n\t" + "pcmpeqd %%mm2, %%mm2 \n\t" + "paddb %%mm2, %%mm2 \n\t" + PAVGB_MMX(%%mm3, %%mm0, %%mm1, %%mm2) + "movq %%mm1, (%2, %%"FF_REG_a") \n\t" + "add %3, %%"FF_REG_a" \n\t" + + "subl $2, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels) + :"D"(block), "r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} + +static void put_no_rnd_pixels8_x2_mmx(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + MOVQ_BFE(mm6); + __asm__ volatile( + "lea (%3, %3), %%"FF_REG_a" \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP_MMX_NO_RND(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP_MMX_NO_RND(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} + +static void put_no_rnd_pixels16_x2_mmx(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + MOVQ_BFE(mm6); + __asm__ volatile( + "lea (%3, %3), %%"FF_REG_a" \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP_MMX_NO_RND(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "movq 8(%1), %%mm0 \n\t" + "movq 9(%1), %%mm1 \n\t" + "movq 8(%1, %3), %%mm2 \n\t" + "movq 9(%1, %3), %%mm3 \n\t" + PAVGBP_MMX_NO_RND(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, 8(%2) \n\t" + "movq %%mm5, 8(%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP_MMX_NO_RND(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "movq 8(%1), %%mm0 \n\t" + "movq 9(%1), %%mm1 \n\t" + "movq 8(%1, %3), %%mm2 \n\t" + "movq 9(%1, %3), %%mm3 \n\t" + PAVGBP_MMX_NO_RND(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, 8(%2) \n\t" + "movq %%mm5, 8(%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} + +static void put_no_rnd_pixels8_y2_mmx(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + MOVQ_BFE(mm6); + __asm__ volatile( + "lea (%3, %3), %%"FF_REG_a" \n\t" + "movq (%1), %%mm0 \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"FF_REG_a"),%%mm2\n\t" + PAVGBP_MMX_NO_RND(%%mm1, %%mm0, %%mm4, %%mm2, %%mm1, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"FF_REG_a"),%%mm0\n\t" + PAVGBP_MMX_NO_RND(%%mm1, %%mm2, %%mm4, %%mm0, %%mm1, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} + +static void avg_no_rnd_pixels16_x2_mmx(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + MOVQ_BFE(mm6); + __asm__ volatile( + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%2), %%mm3 \n\t" + PAVGB_MMX_NO_RND(%%mm0, %%mm1, %%mm2, %%mm6) + PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6) + "movq %%mm0, (%2) \n\t" + "movq 8(%1), %%mm0 \n\t" + "movq 9(%1), %%mm1 \n\t" + "movq 8(%2), %%mm3 \n\t" + PAVGB_MMX_NO_RND(%%mm0, %%mm1, %%mm2, %%mm6) + PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6) + "movq %%mm0, 8(%2) \n\t" + "add %3, %1 \n\t" + "add %3, %2 \n\t" + "subl $1, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((x86_reg)line_size) + :"memory"); +} + +static void avg_no_rnd_pixels8_y2_mmx(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + MOVQ_BFE(mm6); + __asm__ volatile( + "lea (%3, %3), %%"FF_REG_a" \n\t" + "movq (%1), %%mm0 \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"FF_REG_a"), %%mm2 \n\t" + PAVGBP_MMX_NO_RND(%%mm1, %%mm0, %%mm4, %%mm2, %%mm1, %%mm5) + "movq (%2), %%mm3 \n\t" + PAVGB_MMX(%%mm3, %%mm4, %%mm0, %%mm6) + "movq (%2, %3), %%mm3 \n\t" + PAVGB_MMX(%%mm3, %%mm5, %%mm1, %%mm6) + "movq %%mm0, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"FF_REG_a"), %%mm0 \n\t" + PAVGBP_MMX_NO_RND(%%mm1, %%mm2, %%mm4, %%mm0, %%mm1, %%mm5) + "movq (%2), %%mm3 \n\t" + PAVGB_MMX(%%mm3, %%mm4, %%mm2, %%mm6) + "movq (%2, %3), %%mm3 \n\t" + PAVGB_MMX(%%mm3, %%mm5, %%mm1, %%mm6) + "movq %%mm2, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} + #if HAVE_MMX CALL_2X_PIXELS(avg_no_rnd_pixels16_y2_mmx, avg_no_rnd_pixels8_y2_mmx, 8) CALL_2X_PIXELS(put_no_rnd_pixels16_y2_mmx, put_no_rnd_pixels8_y2_mmx, 8) @@ -101,7 +348,6 @@ CALL_2X_PIXELS(put_no_rnd_pixels16_xy2_mmx, put_no_rnd_pixels8_xy2_mmx, 8) #define SET_RND MOVQ_WTWO #define DEF(x, y) ff_ ## x ## _ ## y ## _mmx #define STATIC -#define NO_AVG #include "rnd_template.c" diff --git a/libavcodec/x86/hpeldsp_rnd_template.c b/libavcodec/x86/hpeldsp_rnd_template.c deleted file mode 100644 index 2bff2d2766..0000000000 --- a/libavcodec/x86/hpeldsp_rnd_template.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * SIMD-optimized halfpel functions are compiled twice for rnd/no_rnd - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2003-2004 Michael Niedermayer - * - * MMX optimization by Nick Kurshev - * mostly rewritten by Michael Niedermayer - * and improved by Zdenek Kabelac - * - * 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 -#include - -// put_pixels -av_unused static void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -{ - MOVQ_BFE(mm6); - __asm__ volatile( - "lea (%3, %3), %%"FF_REG_a" \n\t" - ".p2align 3 \n\t" - "1: \n\t" - "movq (%1), %%mm0 \n\t" - "movq 1(%1), %%mm1 \n\t" - "movq (%1, %3), %%mm2 \n\t" - "movq 1(%1, %3), %%mm3 \n\t" - PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) - "movq %%mm4, (%2) \n\t" - "movq %%mm5, (%2, %3) \n\t" - "add %%"FF_REG_a", %1 \n\t" - "add %%"FF_REG_a", %2 \n\t" - "movq (%1), %%mm0 \n\t" - "movq 1(%1), %%mm1 \n\t" - "movq (%1, %3), %%mm2 \n\t" - "movq 1(%1, %3), %%mm3 \n\t" - PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) - "movq %%mm4, (%2) \n\t" - "movq %%mm5, (%2, %3) \n\t" - "add %%"FF_REG_a", %1 \n\t" - "add %%"FF_REG_a", %2 \n\t" - "subl $4, %0 \n\t" - "jnz 1b \n\t" - :"+g"(h), "+S"(pixels), "+D"(block) - :"r"((x86_reg)line_size) - :FF_REG_a, "memory"); -} - -av_unused static void DEF(put, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -{ - MOVQ_BFE(mm6); - __asm__ volatile( - "lea (%3, %3), %%"FF_REG_a" \n\t" - ".p2align 3 \n\t" - "1: \n\t" - "movq (%1), %%mm0 \n\t" - "movq 1(%1), %%mm1 \n\t" - "movq (%1, %3), %%mm2 \n\t" - "movq 1(%1, %3), %%mm3 \n\t" - PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) - "movq %%mm4, (%2) \n\t" - "movq %%mm5, (%2, %3) \n\t" - "movq 8(%1), %%mm0 \n\t" - "movq 9(%1), %%mm1 \n\t" - "movq 8(%1, %3), %%mm2 \n\t" - "movq 9(%1, %3), %%mm3 \n\t" - PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) - "movq %%mm4, 8(%2) \n\t" - "movq %%mm5, 8(%2, %3) \n\t" - "add %%"FF_REG_a", %1 \n\t" - "add %%"FF_REG_a", %2 \n\t" - "movq (%1), %%mm0 \n\t" - "movq 1(%1), %%mm1 \n\t" - "movq (%1, %3), %%mm2 \n\t" - "movq 1(%1, %3), %%mm3 \n\t" - PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) - "movq %%mm4, (%2) \n\t" - "movq %%mm5, (%2, %3) \n\t" - "movq 8(%1), %%mm0 \n\t" - "movq 9(%1), %%mm1 \n\t" - "movq 8(%1, %3), %%mm2 \n\t" - "movq 9(%1, %3), %%mm3 \n\t" - PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) - "movq %%mm4, 8(%2) \n\t" - "movq %%mm5, 8(%2, %3) \n\t" - "add %%"FF_REG_a", %1 \n\t" - "add %%"FF_REG_a", %2 \n\t" - "subl $4, %0 \n\t" - "jnz 1b \n\t" - :"+g"(h), "+S"(pixels), "+D"(block) - :"r"((x86_reg)line_size) - :FF_REG_a, "memory"); -} - -av_unused static void DEF(put, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -{ - MOVQ_BFE(mm6); - __asm__ volatile( - "lea (%3, %3), %%"FF_REG_a" \n\t" - "movq (%1), %%mm0 \n\t" - ".p2align 3 \n\t" - "1: \n\t" - "movq (%1, %3), %%mm1 \n\t" - "movq (%1, %%"FF_REG_a"),%%mm2\n\t" - PAVGBP(%%mm1, %%mm0, %%mm4, %%mm2, %%mm1, %%mm5) - "movq %%mm4, (%2) \n\t" - "movq %%mm5, (%2, %3) \n\t" - "add %%"FF_REG_a", %1 \n\t" - "add %%"FF_REG_a", %2 \n\t" - "movq (%1, %3), %%mm1 \n\t" - "movq (%1, %%"FF_REG_a"),%%mm0\n\t" - PAVGBP(%%mm1, %%mm2, %%mm4, %%mm0, %%mm1, %%mm5) - "movq %%mm4, (%2) \n\t" - "movq %%mm5, (%2, %3) \n\t" - "add %%"FF_REG_a", %1 \n\t" - "add %%"FF_REG_a", %2 \n\t" - "subl $4, %0 \n\t" - "jnz 1b \n\t" - :"+g"(h), "+S"(pixels), "+D"(block) - :"r"((x86_reg)line_size) - :FF_REG_a, "memory"); -} - -av_unused static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -{ - MOVQ_BFE(mm6); - __asm__ volatile( - ".p2align 3 \n\t" - "1: \n\t" - "movq (%1), %%mm0 \n\t" - "movq 1(%1), %%mm1 \n\t" - "movq (%2), %%mm3 \n\t" - PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) - PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6) - "movq %%mm0, (%2) \n\t" - "movq 8(%1), %%mm0 \n\t" - "movq 9(%1), %%mm1 \n\t" - "movq 8(%2), %%mm3 \n\t" - PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) - PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6) - "movq %%mm0, 8(%2) \n\t" - "add %3, %1 \n\t" - "add %3, %2 \n\t" - "subl $1, %0 \n\t" - "jnz 1b \n\t" - :"+g"(h), "+S"(pixels), "+D"(block) - :"r"((x86_reg)line_size) - :"memory"); -} - -av_unused static void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) -{ - MOVQ_BFE(mm6); - __asm__ volatile( - "lea (%3, %3), %%"FF_REG_a" \n\t" - "movq (%1), %%mm0 \n\t" - ".p2align 3 \n\t" - "1: \n\t" - "movq (%1, %3), %%mm1 \n\t" - "movq (%1, %%"FF_REG_a"), %%mm2 \n\t" - PAVGBP(%%mm1, %%mm0, %%mm4, %%mm2, %%mm1, %%mm5) - "movq (%2), %%mm3 \n\t" - PAVGB_MMX(%%mm3, %%mm4, %%mm0, %%mm6) - "movq (%2, %3), %%mm3 \n\t" - PAVGB_MMX(%%mm3, %%mm5, %%mm1, %%mm6) - "movq %%mm0, (%2) \n\t" - "movq %%mm1, (%2, %3) \n\t" - "add %%"FF_REG_a", %1 \n\t" - "add %%"FF_REG_a", %2 \n\t" - - "movq (%1, %3), %%mm1 \n\t" - "movq (%1, %%"FF_REG_a"), %%mm0 \n\t" - PAVGBP(%%mm1, %%mm2, %%mm4, %%mm0, %%mm1, %%mm5) - "movq (%2), %%mm3 \n\t" - PAVGB_MMX(%%mm3, %%mm4, %%mm2, %%mm6) - "movq (%2, %3), %%mm3 \n\t" - PAVGB_MMX(%%mm3, %%mm5, %%mm1, %%mm6) - "movq %%mm2, (%2) \n\t" - "movq %%mm1, (%2, %3) \n\t" - "add %%"FF_REG_a", %1 \n\t" - "add %%"FF_REG_a", %2 \n\t" - - "subl $4, %0 \n\t" - "jnz 1b \n\t" - :"+g"(h), "+S"(pixels), "+D"(block) - :"r"((x86_reg)line_size) - :FF_REG_a, "memory"); -} diff --git a/libavcodec/x86/rnd_template.c b/libavcodec/x86/rnd_template.c index b825eeba6e..4590aeddf0 100644 --- a/libavcodec/x86/rnd_template.c +++ b/libavcodec/x86/rnd_template.c @@ -96,82 +96,3 @@ av_unused STATIC void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixel :"D"(block), "r"((x86_reg)line_size) :FF_REG_a, "memory"); } - -#ifndef NO_AVG -// avg_pixels -// this routine is 'slightly' suboptimal but mostly unused -av_unused STATIC void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, - ptrdiff_t line_size, int h) -{ - MOVQ_ZERO(mm7); - SET_RND(mm6); // =2 for rnd and =1 for no_rnd version - __asm__ volatile( - "movq (%1), %%mm0 \n\t" - "movq 1(%1), %%mm4 \n\t" - "movq %%mm0, %%mm1 \n\t" - "movq %%mm4, %%mm5 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm4 \n\t" - "punpckhbw %%mm7, %%mm1 \n\t" - "punpckhbw %%mm7, %%mm5 \n\t" - "paddusw %%mm0, %%mm4 \n\t" - "paddusw %%mm1, %%mm5 \n\t" - "xor %%"FF_REG_a", %%"FF_REG_a" \n\t" - "add %3, %1 \n\t" - ".p2align 3 \n\t" - "1: \n\t" - "movq (%1, %%"FF_REG_a"), %%mm0 \n\t" - "movq 1(%1, %%"FF_REG_a"), %%mm2 \n\t" - "movq %%mm0, %%mm1 \n\t" - "movq %%mm2, %%mm3 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" - "punpckhbw %%mm7, %%mm1 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "paddusw %%mm2, %%mm0 \n\t" - "paddusw %%mm3, %%mm1 \n\t" - "paddusw %%mm6, %%mm4 \n\t" - "paddusw %%mm6, %%mm5 \n\t" - "paddusw %%mm0, %%mm4 \n\t" - "paddusw %%mm1, %%mm5 \n\t" - "psrlw $2, %%mm4 \n\t" - "psrlw $2, %%mm5 \n\t" - "movq (%2, %%"FF_REG_a"), %%mm3 \n\t" - "packuswb %%mm5, %%mm4 \n\t" - "pcmpeqd %%mm2, %%mm2 \n\t" - "paddb %%mm2, %%mm2 \n\t" - PAVGB_MMX(%%mm3, %%mm4, %%mm5, %%mm2) - "movq %%mm5, (%2, %%"FF_REG_a") \n\t" - "add %3, %%"FF_REG_a" \n\t" - - "movq (%1, %%"FF_REG_a"), %%mm2 \n\t" // 0 <-> 2 1 <-> 3 - "movq 1(%1, %%"FF_REG_a"), %%mm4 \n\t" - "movq %%mm2, %%mm3 \n\t" - "movq %%mm4, %%mm5 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" - "punpcklbw %%mm7, %%mm4 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "punpckhbw %%mm7, %%mm5 \n\t" - "paddusw %%mm2, %%mm4 \n\t" - "paddusw %%mm3, %%mm5 \n\t" - "paddusw %%mm6, %%mm0 \n\t" - "paddusw %%mm6, %%mm1 \n\t" - "paddusw %%mm4, %%mm0 \n\t" - "paddusw %%mm5, %%mm1 \n\t" - "psrlw $2, %%mm0 \n\t" - "psrlw $2, %%mm1 \n\t" - "movq (%2, %%"FF_REG_a"), %%mm3 \n\t" - "packuswb %%mm1, %%mm0 \n\t" - "pcmpeqd %%mm2, %%mm2 \n\t" - "paddb %%mm2, %%mm2 \n\t" - PAVGB_MMX(%%mm3, %%mm0, %%mm1, %%mm2) - "movq %%mm1, (%2, %%"FF_REG_a") \n\t" - "add %3, %%"FF_REG_a" \n\t" - - "subl $2, %0 \n\t" - "jnz 1b \n\t" - :"+g"(h), "+S"(pixels) - :"D"(block), "r"((x86_reg)line_size) - :FF_REG_a, "memory"); -} -#endif From git at videolan.org Mon Jun 2 14:53:48 2025 From: git at videolan.org (=?UTF-8?Q?Andreas_Rheinhardt?=) Date: Mon, 02 Jun 2025 11:53:48 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?avcodec/vc1dsp=3A_Fix_vc1op=5Fpixels?= =?utf-8?q?=5Ffunc_semantics?= Message-ID: <20250602115349.F2F27412A71@natalya.videolan.org> ffmpeg | branch: master | Andreas Rheinhardt | Fri May 30 14:56:57 2025 +0200| [93e53e253a5b723db18cf3c804569191cb1d610a] | committer: Andreas Rheinhardt avcodec/vc1dsp: Fix vc1op_pixels_func semantics Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=93e53e253a5b723db18cf3c804569191cb1d610a --- libavcodec/vc1dsp.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/vc1dsp.h b/libavcodec/vc1dsp.h index e3b90d2b62..b018537af3 100644 --- a/libavcodec/vc1dsp.h +++ b/libavcodec/vc1dsp.h @@ -30,7 +30,9 @@ #include "hpeldsp.h" #include "h264chroma.h" -typedef void (*vc1op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, ptrdiff_t line_size, int h); +typedef void (*vc1op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, + const uint8_t *pixels/*align 1*/, + ptrdiff_t line_size, int round); typedef struct VC1DSPContext { /* vc1 functions */ From git at videolan.org Tue Jun 3 02:08:18 2025 From: git at videolan.org (=?UTF-8?Q?Ramiro_Polla?=) Date: Mon, 02 Jun 2025 23:08:18 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?fftools/Makefile=3A_clean_files_from_f?= =?utf-8?q?ftools/=7Bgraph=2Ctextformat=7D/?= Message-ID: <20250602230819.AD572412917@natalya.videolan.org> ffmpeg | branch: master | Ramiro Polla | Tue May 27 03:33:28 2025 +0200| [afb91360eabbbb343236b1cf37979c848032ff7d] | committer: Ramiro Polla fftools/Makefile: clean files from fftools/{graph,textformat}/ > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=afb91360eabbbb343236b1cf37979c848032ff7d --- fftools/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fftools/Makefile b/fftools/Makefile index c1eba733da..b3c08ae5a0 100644 --- a/fftools/Makefile +++ b/fftools/Makefile @@ -92,4 +92,4 @@ uninstall-progs: $(RM) $(addprefix "$(BINDIR)/", $(ALLAVPROGS)) clean:: - $(RM) $(ALLAVPROGS) $(ALLAVPROGS_G) $(CLEANSUFFIXES:%=fftools/%) + $(RM) $(ALLAVPROGS) $(ALLAVPROGS_G) $(CLEANSUFFIXES:%=fftools/%) $(CLEANSUFFIXES:%=fftools/graph/%) $(CLEANSUFFIXES:%=fftools/textformat/%) From git at videolan.org Tue Jun 3 04:12:45 2025 From: git at videolan.org (=?UTF-8?Q?Emma_Worley?=) Date: Tue, 03 Jun 2025 01:12:45 +0000 Subject: [FFmpeg-cvslog] =?utf-8?q?Add_myself_to_MAINTAINERS_for_dxv/dxve?= =?utf-8?q?nc?= Message-ID: <20250603011246.C0A4D412781@natalya.videolan.org> ffmpeg | branch: master | Emma Worley | Fri May 30 12:33:08 2025 -0700| [854b8690a6287564ace837623acf7c9e0250781d] | committer: Michael Niedermayer Add myself to MAINTAINERS for dxv/dxvenc Signed-off-by: Emma Worley Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=854b8690a6287564ace837623acf7c9e0250781d --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index d1d87752b9..0fba390938 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -176,6 +176,7 @@ Codecs: dss_sp.c Oleksij Rempel dv.c Roman Shaposhnik dvbsubdec.c Anshul Maheshwari + dxv.*, dxvenc.* Emma Worley eacmv*, eaidct*, eat* Peter Ross exif.c, exif.h Thilo Borgmann ffv1* [2] Michael Niedermayer