diff --git a/Changelog b/Changelog index 727b4e60d..65e99845c 100644 --- a/Changelog +++ b/Changelog @@ -1,6 +1,162 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. + +version 8.1.2: + swscale/x86/rgb_2_rgb: fix uyvytoyuv422 overwrite on odd width + swscale/aarch64: fix uyvy/yuyv to yuv420p/yuv422p on odd width + avcodec/snowenc: fix SIGFPE in get_dc() when a block lies outside the plane + avcodec/snowenc: fix out-of-bounds OBMC read in get_dc() for narrow planes + (fforge/pr/23505) avformat/tls_gnutls:fix crash when connecting to peer + libavcodec/jpeg2000htdec: remove trailing whitespace + libavdevice/alsa.c: fix NULL pointer dereference + avcodec/libjxlenc: check orientation tag metadata before reading + avformat/icecast: reject CR/LF in metadata header values + avfilter/avf_showspectrum: Fix allocation check + avformat/sctp: add size check in sctp_read() matching sctp_write() + avcodec/jpeg2000: Fix undefined behavior on ROI shift-up + aacdec_usac_mps212: reject reserved freq_res value + avcodec/aac/aacdec_usac_mps212: Off-by-one bounds check in ff_aac_ec_data_deci() + Update for 8.1.2 + avcodec/snowenc: fix out-of-bounds memcpy in get_block_rd() for narrow planes + avutil/eval: apply unary sign to print, squish, gauss and lerp + avcodec/cbs_av1_syntax_template: reset seen_frame_header on sequence headers + avfilter/convolution: compute user matrix products in unsigned + avformat/mpegts: use av_fast_realloc() for prg + avfilter/avf_showcwt: fix DIRECTION_DU EOF fill clearing the wrong rows + avfilter/avf_showcwt: fix DIRECTION_RL EOF fill clearing the wrong columns + avfilter/avf_showcwt: avoid undefined float to int conversion of nb_consumed_samples + avfilter/avf_showcwt: fix out of array read in compute_kernel + avfilter/v360: compute remap table offsets in 64bit + avfilter/v360: reject out-of-range dimensions + swresample/x86/resample: write only int16 in the int16 resampler + avformat/rtpenc_amr: Check input size + swscale/ppc: fix ASAN stack-buffer-overflow in yuv2planeX + swscale/ppc: fix LOAD_FILTER overread in VSX path + avcodec/sanm: reject codec37 frames taller than the allocated buffer + avcodec/sanm: reject codec47 frames taller than the allocated buffer + avfilter: use ff_slice_pos() for per-slice boundary computation + avfilter: add ff_slice_pos() helper for slice boundaries + (origin/release/8.1, fforge/release/8.1) avformat/iamf_writer: reject muxing PCM streams + avfilter/estdif: avoid signed overflow in slice boundary calculation + swscale: support sliced input with cascaded scaling contexts + avformat/rtspdec: bound Content-Length in the ANNOUNCE handler to SDP_MAX_SIZE + avcodec/cbs_h266_syntax_template: reject subpic info with res_change_in_clvs + avcodec/misc4: Check nb channels + avcodec/rv10, rv34: check init_get_bits8() before RealVideo bit access + avformat/http: reject request-line tokens not terminated by whitespace + avformat/mov: reject out of range ispe dimensions, avoid overflow summing HEIF tile dimensions + avcodec/agm: validate actual src_y against prev plane in decode_inter_plane + avformat/dhav: Fix second integer overflow in get_duration() + fftools/ffmpeg_dec: deep-copy subtitle_header to fix use-after-free + avcodec/hevc/ps: Check window parameters + avcodec/hevc/ps: Factor window reading out + avcodec/truespeech: reject iterations count whose * 240 product overflows 32-bit + libavcodec/options_table: gamma22 and gamma28 aliases + avcodec/on2avc: reject subframe count whose * SUBFRAME_SIZE product overflows 32-bit + avfilter/zmq: initialize send_buf before shared cleanup on parse failure + avcodec/adpcm: fix signed integer overflow in get_nb_samples() + avformat/matroskadec: avoid signed overflow in DASH cue time differences + avcodec/fastaudio: reject subframes count whose * 256 product overflows 32-bit + avcodec/vc2enc_dwt: avoid signed overflow in the 9/7 DWT lifting + avcodec/vc2enc_dwt: avoid signed overflow in the 5/3 and Haar DWT + avformat/dashdec: Fail with any inner stream count being 0 + avcodec/mjpegdec: require progress in AVRn interlaced field loop + avcodec/mwsc: do not dereference a missing reference frame + avcodec/misc4: reject invalid sample rate + swscale/output: avoid signed overflow in yuv2rgba64_1 alpha + swscale/output: avoid signed overflow in yuv2rgba64_full_1 alpha + tools/target_dem_fuzzer: do not exit on io_buffer allocation failure + avformat/gxfenc: Check timecode and propagate error + swscale/rgb2rgb_template: use unsigned for <<24 + avformat/iamf_parse: bound substream count by remaining OBU size + avformat/matroskadec: bound TRACKENTRY parsing by max_streams + avcodec/diracdec: fix heap buffer overflow in edge_emu_buffer + avformat/rtmppkt: Check recursion depth + avcodec/tdsc: propagate max_pixels to the JPEG tile decoder + avcodec/imm5: propagate max_pixels to the H264/HEVC sub-decoders + avcodec/cri: propagate max_pixels to the JPEG tile decoder + avcodec/jpeglsdec: only apply color transform to decoded rows + avcodec/adpcm: require block_align to be a multiple of channels in ADPCM_PSXC init + avfilter/avf_showcwt: fix out-of-bounds read in du scroll + avfilter/f_ebur128: avoid signed-int wrap when sizing per-channel cache + avformat/mov: cap HEIF ICC profile copies via c*max_streams to bound CPU and memory + avcodec/aac/aacdec_usac: reject explicit usacSamplingFrequency of 0 + avcodec/aac/aacdec_usac: avoid signed overflow in decode_tsd + avcodec/aac/aacdec: reject decoded frame without a valid sample rate + avformat/iff: check av_get_packet() result in ANIM branch + avcodec/cbs_h266_syntax_template: Fix pps_exp_slice_height_in_ctus_minus1 range + avfilter/vf_scale: split rational multiply + avcodec/bsf/dts2pts: fix binary tree invariant violation on selective dec_poc + avfilter/vf_drawtext: Avoid double free in glyph_enu_border_free() + avfilter/vf_drawtext: plug error-path leaks in measure_text/draw_text + avfilter/vf_drawtext: shape_text_hb() free allocated things on error + avfilter/vf_drawtext: avoid double-free of aliased FT_Glyph in glyph_enu_free + avfilter/vf_drawtext: don't double-free glyph that has been cached in tree + avfilter/vf_drawtext: always check pixel_mode == FT_PIXEL_MODE_MONO + avcodec/cook: bound subpacket channel sum against channel count + avcodec/apv_decode: avoid using apv_cbc + avformat/mxfdec: Remove unneeded check + avformat/ftp: Check string used for RNTO + avformat/ftp: Check for Telnet IAC characters and other non printable ASCII chars + avformat/ftp: reject CR/LF in the URL path to prevent FTP command injection + avcodec/jpeg2000dec: Clear header derived variables + avcodec/bsf/smpte436m_to_eia608: properly frees stuff on errors in ff_smpte436m_to_eia608_filter() + tests/checkasm/crc: retain offset values between calls + avformat/avc: Adjust get_ue_golomb() to handle 32 bit + avformat/whip: require remote DTLS fingerprint in SDP answer + avcodec/x86/vorbisdsp: change cmpleps to cmpltps in inverse coupling + avcodec/liboapvenc: derive and validate APV profile from pixel format + avformat/dashdec: bound manifest reloads and fragment-open retries + avfilter/af_join: fix wrong loop bound in buffer dedup (use-after-free) + avcodec/nvenc: fix compatibility with Video Codec SDK 13.1 + avformat/mov: validate APV access unit length before passing to decoder + avcodec/h264_slice: guard color_frame() against chroma-width underflow + avcodec/magicyuv: reject slice_height misaligned with chroma vshift + avcodec/magicyuv: Expand the s->interlaced slice-height sanity check + avcodec/magicyuv: Fix 1 line MEDIAN slices + avformat/mxfdec: zero-init Sony MPEG-4 extradata and add padding + avformat/soxdec: Check sample_rate for nan + tests/tiny_ssim: fixed mistake in ssim_c1 calculation + avformat/hls: Check TIME-OFFSET value + avformat/hls: Check url_offset and size + avcodec/prores_raw: reject invalid tile alignment values + avformat/ty: check rec_size + avformat/ogg: Fix overflow and stale oggvorbis_private values + avformat/rtpenc_xiph: bail out when the max payload size underflows + avformat/rtpenc_aac: reject packets smaller than the ADTS header + avcodec/jpeg2000dec: compute mask in decode_clnpass() like in decode_sigpass() + avformat/flvdec: Check size at the top of the main loop + avformat/vividas: fix misaligned access + avformat/mccdec: dont pass NULL to bytestream2_put_buffer() + avcodec/g2meet: The stack is EPIC_PIX_STACK_SIZE + avcodec/h2645_sei: Initialize side data before deallocation + avfilter/boxblur: Fix off by one errors + avformat/assenc: Add the missing parentheses + avcodec/diracdec: Enlarge `mctmp` to cover the worst-case `blheight·ybsep + yblen` rows, and break the MC loop when no output rows remain + tools/zmqsend: free the AVBprint buffer after using it + [Wave] Fix issues with unaligned metadata chunks. + avformat/mpegts: Dont assume fc->priv_data is a MpegTSContext + fftools/graph: Add missing include "libavutil/mem.h" for fftools/graph/graphprint.c + avcodec/cbs_h266_syntax_template: tighten sh_num_tiles_in_slice_minus1 upper bound + avcodec/hevc: limit missing-ref fill to coded planes + avformat/mov: Fix negative index given to can_seek_to_key_sample() + avcodec/hdrdec: fix pixel count decrement in RLE decompress loop + (fforge/pr/23464) forgejo/workflows: update test workflow for 8.1 release + (fforge/pr/23445) aarch64: vp9lpf: Fix GCS violations + (fforge/pr/23303) avformat/mov: don't abort on unsupported or invalid chnl boxes + avformat/mov_chan: keep the layout untouched on chan/chnl box failure + (fforge/pr/23240) avformat/oggparsevorbis.c: Prevent integer overflow when summing header lengths; add bounds check. + (fforge/pr/23187) avformat/oggparsecelt: bound extra_headers to avoid an effectively infinite loop + (fforge/pr/23111) avformat/demux: use correct close function for custom io + avformat/hlsenc: use correct close function for custom io + avformat/hlsenc: respect io_open set in AVFormatContext + avformat/dashenc: respect io_open set in AVFormatContext + avformat/dashdec: respect io_open set in AVFormatContext + vulkan: fix using encode caps before querying + avformat/rtpdec_av1: fix buffer overflow due to variable confusion + + version 8.1.1: avcodec/aac/aacdec_usac_mps212: fix attach_lsb() OOB after huff_decode avcodec/dfpwmdec: Check nb_samples diff --git a/RELEASE b/RELEASE index 0e7915245..6b409d977 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -8.1.1 +8.1.2 diff --git a/VERSION b/VERSION index 0e7915245..6b409d977 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.1.1 +8.1.2 diff --git a/build.yaml b/build.yaml index 78b1ddce5..b31ce6e7c 100644 --- a/build.yaml +++ b/build.yaml @@ -1,7 +1,7 @@ --- # We just wrap `build` so this is really it name: "jellyfin-ffmpeg" -version: "8.1.1-4" +version: "8.1.2-1" packages: - bullseye-amd64 - bullseye-arm64 diff --git a/builder/scripts.d/25-openssl.sh b/builder/scripts.d/25-openssl.sh index c72ef1454..315f0d2f0 100755 --- a/builder/scripts.d/25-openssl.sh +++ b/builder/scripts.d/25-openssl.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/openssl/openssl.git" -SCRIPT_COMMIT="openssl-3.6.2" +SCRIPT_COMMIT="openssl-3.6.3" SCRIPT_TAGFILTER="openssl-3.6.*" ffbuild_enabled() { diff --git a/builder/scripts.d/45-harfbuzz.sh b/builder/scripts.d/45-harfbuzz.sh index a312e11e2..9fd948320 100755 --- a/builder/scripts.d/45-harfbuzz.sh +++ b/builder/scripts.d/45-harfbuzz.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/harfbuzz/harfbuzz.git" -SCRIPT_COMMIT="b0ffab42d473eb380ad0fcf42730e0f1868cbc97" +SCRIPT_COMMIT="56feae4035bdd48f62ba2b8d8c16232d4d89b3a4" ffbuild_enabled() { return 0 diff --git a/builder/scripts.d/47-vulkan/45-vulkan-headers.sh b/builder/scripts.d/47-vulkan/45-vulkan-headers.sh index b7537f361..55049512c 100755 --- a/builder/scripts.d/47-vulkan/45-vulkan-headers.sh +++ b/builder/scripts.d/47-vulkan/45-vulkan-headers.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/KhronosGroup/Vulkan-Headers.git" -SCRIPT_COMMIT="v1.4.349" +SCRIPT_COMMIT="v1.4.355" SCRIPT_TAGFILTER="v?.*.*" ffbuild_enabled() { diff --git a/builder/scripts.d/47-vulkan/45-vulkan-loader.sh b/builder/scripts.d/47-vulkan/45-vulkan-loader.sh index f8a47ba8e..68dbea635 100755 --- a/builder/scripts.d/47-vulkan/45-vulkan-loader.sh +++ b/builder/scripts.d/47-vulkan/45-vulkan-loader.sh @@ -4,7 +4,7 @@ SCRIPT_REPO="https://github.com/BtbN/Vulkan-Shim-Loader.git" SCRIPT_COMMIT="65b3936528cd92eb4ea3de485d03f858a3850484" SCRIPT_REPO2="https://github.com/KhronosGroup/Vulkan-Headers.git" -SCRIPT_COMMIT2="v1.4.349" +SCRIPT_COMMIT2="v1.4.355" SCRIPT_TAGFILTER2="v?.*.*" ffbuild_enabled() { diff --git a/builder/scripts.d/47-vulkan/50-shaderc.sh b/builder/scripts.d/47-vulkan/50-shaderc.sh index 55bbcefd3..9e612a326 100755 --- a/builder/scripts.d/47-vulkan/50-shaderc.sh +++ b/builder/scripts.d/47-vulkan/50-shaderc.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/google/shaderc.git" -SCRIPT_COMMIT="301b4ede53d59b68bf55f95bb26412d9233c8187" +SCRIPT_COMMIT="d5f08ae5c5a9a45165578445cbd0f9adf0223448" ffbuild_enabled() { [[ $TARGET == mac* ]] && return -1 diff --git a/builder/scripts.d/47-vulkan/55-spirv-cross.sh b/builder/scripts.d/47-vulkan/55-spirv-cross.sh index 1759cb5b8..8e4a7a6d9 100755 --- a/builder/scripts.d/47-vulkan/55-spirv-cross.sh +++ b/builder/scripts.d/47-vulkan/55-spirv-cross.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/KhronosGroup/SPIRV-Cross.git" -SCRIPT_COMMIT="b9ded926bd2ec460b8d60d5c9678808bf8cbdd9b" +SCRIPT_COMMIT="1a6169566c73d3da552748fc372fe2bbb856e46e" ffbuild_enabled() { [[ $TARGET == mac* ]] && return -1 diff --git a/builder/scripts.d/50-amf.sh b/builder/scripts.d/50-amf.sh index b472ce9aa..8522eb03a 100755 --- a/builder/scripts.d/50-amf.sh +++ b/builder/scripts.d/50-amf.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/GPUOpen-LibrariesAndSDKs/AMF.git" -SCRIPT_COMMIT="d0b3e6dd544a5f207bb6a12a1ecb98532491176a" +SCRIPT_COMMIT="eadd00804d5f7e5cd8c85d540073198312870776" ffbuild_enabled() { [[ $TARGET == mac* ]] && return -1 diff --git a/builder/scripts.d/50-libass.sh b/builder/scripts.d/50-libass.sh index 4187841fa..6c697fc5a 100755 --- a/builder/scripts.d/50-libass.sh +++ b/builder/scripts.d/50-libass.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/libass/libass.git" -SCRIPT_COMMIT="bbb3c7f1570a4a021e52683f3fbdf74fe492ae84" +SCRIPT_COMMIT="4a05d8127f525943ebf45fdc6497c9e665947f0d" ffbuild_enabled() { return 0 diff --git a/builder/scripts.d/50-libvpl.sh b/builder/scripts.d/50-libvpl.sh index 64e5cde58..334458252 100755 --- a/builder/scripts.d/50-libvpl.sh +++ b/builder/scripts.d/50-libvpl.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/intel/libvpl.git" -SCRIPT_COMMIT="778a66d6c6537f08eabb91955dbbf1bce3812894" +SCRIPT_COMMIT="d77f9195cf495b937631607333288fd917ae8939" ffbuild_enabled() { [[ $TARGET == mac* ]] && return -1 @@ -17,7 +17,7 @@ ffbuild_dockerbuild() { cmake -GNinja -DCMAKE_TOOLCHAIN_FILE="$FFBUILD_CMAKE_TOOLCHAIN" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$FFBUILD_PREFIX" \ -DCMAKE_INSTALL_BINDIR="$FFBUILD_PREFIX"/bin -DCMAKE_INSTALL_LIBDIR="$FFBUILD_PREFIX"/lib \ - -DINSTALL_DEV=ON -DINSTALL_LIB=ON \ + -DINSTALL_DEV=ON -DINSTALL_LIB=ON -DINSTALL_EXAMPLES=OFF \ -DBUILD_EXAMPLES=OFF -DBUILD_EXPERIMENTAL=OFF \ -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF .. diff --git a/builder/scripts.d/50-openmpt.sh b/builder/scripts.d/50-openmpt.sh index ec5aebf48..ecd611762 100755 --- a/builder/scripts.d/50-openmpt.sh +++ b/builder/scripts.d/50-openmpt.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/OpenMPT/openmpt.git" -SCRIPT_COMMIT="a2b251c67ca757bb181a0cd4cc97e9e94bfe2608" +SCRIPT_COMMIT="11363ff11ba021b1cf1533da17d9fdf20c8d883c" ffbuild_enabled() { return 0 diff --git a/debian/changelog b/debian/changelog index ca90a53e3..8c8442ac0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +jellyfin-ffmpeg (8.1.2-1) unstable; urgency=medium + + * New upstream version 8.1.2 + * Fix a conflict between VPP tonemap and specific scaling mode + * Fix typos in some shader based deint filters + * Update build scripts and dependencies + + -- nyanmisaka Sun, 28 Jun 2026 17:07:36 +0800 + jellyfin-ffmpeg (8.1.1-4) unstable; urgency=medium * Fix broken macro place for scale_vt patch diff --git a/debian/patches/0007-add-bt2390-eetf-and-code-refactor-to-opencl-tonemap.patch b/debian/patches/0007-add-bt2390-eetf-and-code-refactor-to-opencl-tonemap.patch index 0657bde4e..6011bbcb8 100644 --- a/debian/patches/0007-add-bt2390-eetf-and-code-refactor-to-opencl-tonemap.patch +++ b/debian/patches/0007-add-bt2390-eetf-and-code-refactor-to-opencl-tonemap.patch @@ -2324,7 +2324,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c + + if (max_compute_units >= 40) + ctx->tradeoff = 0; -+ else if (device_name) { ++ else if (device_name) { + const char *excluded_devices[5] = { "Arc", "Iris", "Xe", "770", "750" }; + for (i = 0; i < FF_ARRAY_ELEMS(excluded_devices); i++) { + if (strstr(device_name, excluded_devices[i])) { diff --git a/debian/patches/0019-add-fixes-for-qsv-vpp-filters.patch b/debian/patches/0019-add-fixes-for-qsv-vpp-filters.patch index b2be7f558..658a38302 100644 --- a/debian/patches/0019-add-fixes-for-qsv-vpp-filters.patch +++ b/debian/patches/0019-add-fixes-for-qsv-vpp-filters.patch @@ -241,7 +241,7 @@ Index: FFmpeg/libavfilter/vf_vpp_qsv.c outvsi_conf.ColourDescriptionPresent = 1; if (memcmp(&vpp->invsi_conf, &invsi_conf, sizeof(mfxExtVideoSignalInfo)) || -@@ -689,12 +718,23 @@ static int config_output(AVFilterLink *o +@@ -689,12 +718,28 @@ static int config_output(AVFilterLink *o if (inlink->w != outlink->w || inlink->h != outlink->h || in_format != vpp->out_format) { if (QSV_RUNTIME_VERSION_ATLEAST(mfx_version, 1, 19)) { @@ -256,10 +256,15 @@ Index: FFmpeg/libavfilter/vf_vpp_qsv.c -#endif + /* Compute mode is only available on DG2+ platforms */ + if (vpl && get_mfx_platform(ctx, &mfx_platform) == MFX_ERR_NONE) { ++ const AVPixFmtDescriptor *in_desc = av_pix_fmt_desc_get(in_format); + int code_name = mfx_platform.CodeName; + compute = code_name >= 45 && + code_name <= 54 && + code_name != 50; ++ /* When used with tonemap, only 4:2:0 chroma is supported */ ++ if (vpp->tonemap && in_desc && ++ !(in_desc->log2_chroma_w && in_desc->log2_chroma_h)) ++ compute = 0; + } + + if (mode == -1) @@ -269,7 +274,7 @@ Index: FFmpeg/libavfilter/vf_vpp_qsv.c INIT_MFX_EXTBUF(scale_conf, MFX_EXTBUFF_VPP_SCALING); SET_MFX_PARAM_FIELD(scale_conf, ScalingMode, mode); -@@ -706,6 +746,13 @@ static int config_output(AVFilterLink *o +@@ -706,6 +751,13 @@ static int config_output(AVFilterLink *o #undef INIT_MFX_EXTBUF #undef SET_MFX_PARAM_FIELD @@ -283,7 +288,7 @@ Index: FFmpeg/libavfilter/vf_vpp_qsv.c if (vpp->use_frc || vpp->use_crop || vpp->deinterlace || vpp->denoise || vpp->detail || vpp->procamp || vpp->rotate || vpp->hflip || inlink->w != outlink->w || inlink->h != outlink->h || in_format != vpp->out_format || -@@ -884,19 +931,13 @@ static const AVOption vpp_options[] = { +@@ -884,19 +936,13 @@ static const AVOption vpp_options[] = { { "height", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 4 }, 0, INT_MAX, .flags = FLAGS }, @@ -304,7 +309,7 @@ Index: FFmpeg/libavfilter/vf_vpp_qsv.c { "rate", "Generate output at frame rate or field rate, available only for deinterlace mode", OFFSET(field_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, .unit = "rate" }, -@@ -927,8 +968,9 @@ static const AVOption vpp_options[] = { +@@ -927,8 +973,9 @@ static const AVOption vpp_options[] = { { "out_color_transfer", "Output color transfer characteristics", OFFSET(color_transfer_str), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS }, @@ -315,7 +320,7 @@ Index: FFmpeg/libavfilter/vf_vpp_qsv.c { NULL } }; -@@ -984,19 +1026,14 @@ static const AVOption qsvscale_options[] +@@ -984,19 +1031,14 @@ static const AVOption qsvscale_options[] { "h", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str = "ih" }, .flags = FLAGS }, { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, @@ -337,7 +342,7 @@ Index: FFmpeg/libavfilter/vf_vpp_qsv.c { NULL }, }; -@@ -1021,6 +1058,7 @@ static const AVOption qsvdeint_options[] +@@ -1021,6 +1063,7 @@ static const AVOption qsvdeint_options[] { "bob", "bob algorithm", 0, AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_BOB}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, .unit = "mode"}, { "advanced", "Motion adaptive algorithm", 0, AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, .unit = "mode"}, diff --git a/debian/patches/0030-tune-dxva-align-for-intel-to-avoid-copy-on-qsv.patch b/debian/patches/0030-tune-dxva-align-for-intel-to-avoid-copy-on-qsv.patch index 13018ec1a..50e6e0117 100644 --- a/debian/patches/0030-tune-dxva-align-for-intel-to-avoid-copy-on-qsv.patch +++ b/debian/patches/0030-tune-dxva-align-for-intel-to-avoid-copy-on-qsv.patch @@ -2,10 +2,11 @@ Index: FFmpeg/libavcodec/dxva2.c =================================================================== --- FFmpeg.orig/libavcodec/dxva2.c +++ FFmpeg/libavcodec/dxva2.c -@@ -616,6 +616,16 @@ int ff_dxva2_common_frame_params(AVCodec +@@ -616,6 +616,18 @@ int ff_dxva2_common_frame_params(AVCodec else surface_alignment = 16; ++#if CONFIG_D3D11VA + /* align surfaces to 32 on Intel to keep in line with the MSDK impl, + which avoids the unnecessary resizing when mapping to QSV */ + if (device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) { @@ -15,11 +16,12 @@ Index: FFmpeg/libavcodec/dxva2.c + surface_alignment = 32; + } + } ++#endif + /* 1 base work surface */ num_surfaces = 1; -@@ -623,9 +633,9 @@ int ff_dxva2_common_frame_params(AVCodec +@@ -623,9 +635,9 @@ int ff_dxva2_common_frame_params(AVCodec if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC) num_surfaces += 16; else if (avctx->codec_id == AV_CODEC_ID_VP9 || avctx->codec_id == AV_CODEC_ID_AV1) diff --git a/debian/patches/0056-add-bwdif-videotoolbox-filter.patch b/debian/patches/0056-add-bwdif-videotoolbox-filter.patch index 6c3e4eb50..53eb01578 100644 --- a/debian/patches/0056-add-bwdif-videotoolbox-filter.patch +++ b/debian/patches/0056-add-bwdif-videotoolbox-filter.patch @@ -2,7 +2,7 @@ Index: FFmpeg/configure =================================================================== --- FFmpeg.orig/configure +++ FFmpeg/configure -@@ -4120,6 +4120,7 @@ boxblur_opencl_filter_deps="opencl gpl" +@@ -4123,6 +4123,7 @@ boxblur_opencl_filter_deps="opencl gpl" bs2b_filter_deps="libbs2b" bwdif_cuda_filter_deps="ffnvcodec" bwdif_cuda_filter_deps_any="cuda_nvcc cuda_llvm" @@ -155,7 +155,7 @@ Index: FFmpeg/libavfilter/metal/vf_bwdif_videotoolbox.metal + if (abs(c - e) > temporal_diff0) { + interpol = (((coef_hf[0] * (prev2_0 + next2_0) + - coef_hf[1] * (prev2_mrefs2 + next2_mrefs2 + prev2_prefs2 + next2_prefs2) -+ + coef_hf[2] * (prev2_mrefs4 + next2_mrefs4 + prev2_prefs4 + next2_mrefs4)) / 4) ++ + coef_hf[2] * (prev2_mrefs4 + next2_mrefs4 + prev2_prefs4 + next2_prefs4)) / 4) + + coef_lf[0] * (c + e) - coef_lf[1] * (cur_mrefs3 + cur_prefs3)) / (1 << 13); + } else { + interpol = (coef_sp[0] * (c + e) - coef_sp[1] * (cur_mrefs3 + cur_prefs3)) / (1 << 13); @@ -196,10 +196,10 @@ Index: FFmpeg/libavfilter/metal/vf_bwdif_videotoolbox.metal + } + + // Calculate temporal prediction -+ texture2d prev2 = prev; -+ texture2d prev1 = is_second_field ? cur : prev; -+ texture2d next1 = is_second_field ? next : cur; -+ texture2d next2 = next; ++ texture2d prev2 = is_second_field ? cur : prev; ++ texture2d prev1 = prev; ++ texture2d next1 = next; ++ texture2d next2 = is_second_field ? next : cur; + + T prev2_prefs4 = tex2D(prev2, pos.x, pos.y+ 4); + T prev2_prefs2 = tex2D(prev2, pos.x, pos.y + 2); @@ -249,10 +249,10 @@ Index: FFmpeg/libavfilter/metal/vf_bwdif_videotoolbox.metal + } + + // Calculate temporal prediction -+ texture2d prev2 = prev; -+ texture2d prev1 = is_second_field ? cur : prev; -+ texture2d next1 = is_second_field ? next : cur; -+ texture2d next2 = next; ++ texture2d prev2 = is_second_field ? cur : prev; ++ texture2d prev1 = prev; ++ texture2d next1 = next; ++ texture2d next2 = is_second_field ? next : cur; + + T prev2_prefs4 = tex2D(prev2, pos.x, pos.y+ 4); + T prev2_prefs2 = tex2D(prev2, pos.x, pos.y + 2); @@ -312,6 +312,40 @@ Index: FFmpeg/libavfilter/metal/vf_bwdif_videotoolbox.metal + } + dst.write(pred.xyyy, pos); +} +Index: FFmpeg/libavfilter/metal/vf_yadif_videotoolbox.metal +=================================================================== +--- FFmpeg.orig/libavfilter/metal/vf_yadif_videotoolbox.metal ++++ FFmpeg/libavfilter/metal/vf_yadif_videotoolbox.metal +@@ -88,7 +88,7 @@ T spatial_predictor(T a, T b, T c, T d, + T h, T i, T j, T k, T l, T m, T n) + { + T spatial_pred = (d + k)/2; +- T spatial_score = abs(c - j) + abs(d - k) + abs(e - l); ++ T spatial_score = abs(c - j) + abs(d - k) + abs(e - l) - (1.0f / 255.0f); + + T score = abs(b - k) + abs(c - l) + abs(d - m); + if (score < spatial_score) { +@@ -128,7 +128,7 @@ T temporal_predictor(T A, T B, T C, T D, + T tdiff1 = (abs(A - F) + abs(B - G)) / 2; + T tdiff2 = (abs(K - F) + abs(G - L)) / 2; + +- T diff = max3(tdiff0, tdiff1, tdiff2); ++ T diff = max3(tdiff0 / 2, tdiff1, tdiff2); + + if (!skip_check) { + T maxi = max3(p2 - p3, p2 - p1, min(p0 - p1, p4 - p3)); +@@ -239,9 +239,9 @@ T yadif( + T spatial_pred = yadif_compute_spatial(cur, pos); + + if (params.is_second_field) { +- return yadif_compute_temporal(cur, prev, cur, next, next, spatial_pred, params.skip_spatial_check, pos); ++ return yadif_compute_temporal(cur, cur, prev, next, next, spatial_pred, params.skip_spatial_check, pos); + } else { +- return yadif_compute_temporal(cur, prev, prev, cur, next, spatial_pred, params.skip_spatial_check, pos); ++ return yadif_compute_temporal(cur, prev, prev, next, cur, spatial_pred, params.skip_spatial_check, pos); + } + } + Index: FFmpeg/libavfilter/vf_bwdif_videotoolbox.m =================================================================== --- /dev/null diff --git a/debian/patches/0069-add-yadif-and-bwdif-opencl-filter-impl.patch b/debian/patches/0069-add-yadif-and-bwdif-opencl-filter-impl.patch index d5c1b13f6..c623c5858 100644 --- a/debian/patches/0069-add-yadif-and-bwdif-opencl-filter-impl.patch +++ b/debian/patches/0069-add-yadif-and-bwdif-opencl-filter-impl.patch @@ -2,7 +2,7 @@ Index: FFmpeg/configure =================================================================== --- FFmpeg.orig/configure +++ FFmpeg/configure -@@ -4121,6 +4121,7 @@ boxblur_opencl_filter_deps="opencl gpl" +@@ -4124,6 +4124,7 @@ boxblur_opencl_filter_deps="opencl gpl" bs2b_filter_deps="libbs2b" bwdif_cuda_filter_deps="ffnvcodec" bwdif_cuda_filter_deps_any="cuda_nvcc cuda_llvm" @@ -10,7 +10,7 @@ Index: FFmpeg/configure bwdif_videotoolbox_filter_deps="metal corevideo videotoolbox" bwdif_vulkan_filter_deps="vulkan spirv_compiler" chromaber_vulkan_filter_deps="vulkan spirv_library" -@@ -4280,6 +4281,7 @@ xfade_opencl_filter_deps="opencl" +@@ -4283,6 +4284,7 @@ xfade_opencl_filter_deps="opencl" xfade_vulkan_filter_deps="vulkan spirv_library" yadif_cuda_filter_deps="ffnvcodec" yadif_cuda_filter_deps_any="cuda_nvcc cuda_llvm" @@ -52,7 +52,7 @@ Index: FFmpeg/libavfilter/allfilters.c extern const FFFilter ff_vf_bwdif_videotoolbox; extern const FFFilter ff_vf_bwdif_vulkan; extern const FFFilter ff_vf_cas; -@@ -562,6 +563,7 @@ extern const FFFilter ff_vf_xpsnr; +@@ -563,6 +564,7 @@ extern const FFFilter ff_vf_xpsnr; extern const FFFilter ff_vf_xstack; extern const FFFilter ff_vf_yadif; extern const FFFilter ff_vf_yadif_cuda; @@ -228,7 +228,7 @@ Index: FFmpeg/libavfilter/opencl/bwdif.cl + if (fabs(c - e) > temporal_diff0) { + interpol = native_divide((((coef_hf[0] * (prev2_0 + next2_0) + - coef_hf[1] * (prev2_mrefs2 + next2_mrefs2 + prev2_prefs2 + next2_prefs2) -+ + coef_hf[2] * (prev2_mrefs4 + next2_mrefs4 + prev2_prefs4 + next2_mrefs4)) * 0.25f) ++ + coef_hf[2] * (prev2_mrefs4 + next2_mrefs4 + prev2_prefs4 + next2_prefs4)) * 0.25f) + + coef_lf[0] * (c + e) - coef_lf[1] * (cur_mrefs3 + cur_prefs3)), (float)(1 << 13)); + } else { + interpol = native_divide((coef_sp[0] * (c + e) - coef_sp[1] * (cur_mrefs3 + cur_prefs3)), (float)(1 << 13)); @@ -322,17 +322,17 @@ Index: FFmpeg/libavfilter/opencl/bwdif.cl + + if (channels == 1) { + float pred = is_second_field -+ ? bwdif_compute_float(dst, cur, prev, cur, next, next, ++ ? bwdif_compute_float(dst, cur, cur, prev, next, next, + parity, is_field_end, pos) -+ : bwdif_compute_float(dst, cur, prev, prev, cur, next, ++ : bwdif_compute_float(dst, cur, prev, prev, next, cur, + parity, is_field_end, pos); + + write_imagef(dst, pos, (float4)(pred, 0.0f, 0.0f, 1.0f)); + } else if (channels == 2) { + float2 pred = is_second_field -+ ? bwdif_compute_float2(dst, cur, prev, cur, next, next, ++ ? bwdif_compute_float2(dst, cur, cur, prev, next, next, + parity, is_field_end, pos) -+ : bwdif_compute_float2(dst, cur, prev, prev, cur, next, ++ : bwdif_compute_float2(dst, cur, prev, prev, next, cur, + parity, is_field_end, pos); + + write_imagef(dst, pos, (float4)(pred.x, pred.y, 0.0f, 1.0f)); @@ -375,7 +375,7 @@ Index: FFmpeg/libavfilter/opencl/yadif.cl + float h, float i, float j, float k, float l, float m, float n) +{ + float spatial_pred = (d + k) * 0.5f; -+ float spatial_score = fabs(c - j) + fabs(d - k) + fabs(e - l); ++ float spatial_score = fabs(c - j) + fabs(d - k) + fabs(e - l) - (1.0f / 255.0f); + + float score = fabs(b - k) + fabs(c - l) + fabs(d - m); + if (score < spatial_score) { @@ -424,7 +424,7 @@ Index: FFmpeg/libavfilter/opencl/yadif.cl + float tdiff1 = (fabs(A - F) + fabs(B - G)) * 0.5f; + float tdiff2 = (fabs(K - F) + fabs(G - L)) * 0.5f; + -+ float diff = max3(tdiff0, tdiff1, tdiff2); ++ float diff = max3(tdiff0 * 0.5f, tdiff1, tdiff2); + + if (!skip_check) { + float maxi = max3(p2 - p3, p2 - p1, min(p0 - p1, p4 - p3)); @@ -523,18 +523,18 @@ Index: FFmpeg/libavfilter/opencl/yadif.cl + if (channels == 1) { + float spatial_pred = yadif_compute_spatial_float(cur, pos); + float pred = is_second_field -+ ? yadif_compute_temporal_float(cur, prev, cur, next, next, ++ ? yadif_compute_temporal_float(cur, cur, prev, next, next, + spatial_pred, skip_spatial_check, pos) -+ : yadif_compute_temporal_float(cur, prev, prev, cur, next, ++ : yadif_compute_temporal_float(cur, prev, prev, next, cur, + spatial_pred, skip_spatial_check, pos); + + write_imagef(dst, pos, (float4)(pred, 0.0f, 0.0f, 1.0f)); + } else if (channels == 2) { + float2 spatial_pred = yadif_compute_spatial_float2(cur, pos); + float2 pred = is_second_field -+ ? yadif_compute_temporal_float2(cur, prev, cur, next, next, ++ ? yadif_compute_temporal_float2(cur, cur, prev, next, next, + spatial_pred, skip_spatial_check, pos) -+ : yadif_compute_temporal_float2(cur, prev, prev, cur, next, ++ : yadif_compute_temporal_float2(cur, prev, prev, next, cur, + spatial_pred, skip_spatial_check, pos); + + write_imagef(dst, pos, (float4)(pred.x, pred.y, 0.0f, 1.0f)); diff --git a/debian/patches/0077-fix-low-default-readrate-catchup-caused-remuxing-to-stall.patch b/debian/patches/0077-fix-low-default-readrate-catchup-caused-remuxing-to-stall.patch deleted file mode 100644 index be7f6a16c..000000000 --- a/debian/patches/0077-fix-low-default-readrate-catchup-caused-remuxing-to-stall.patch +++ /dev/null @@ -1,22 +0,0 @@ -Index: FFmpeg/fftools/ffmpeg_demux.c -=================================================================== ---- FFmpeg.orig/fftools/ffmpeg_demux.c -+++ FFmpeg/fftools/ffmpeg_demux.c -@@ -534,7 +534,7 @@ static void readrate_sleep(Demuxer *d) - ds->lag = lag; - ds->resume_wc = now; - ds->resume_pts = pts; -- av_log_once(ds, AV_LOG_WARNING, AV_LOG_DEBUG, &resume_warn, -+ av_log_once(ds, AV_LOG_VERBOSE, AV_LOG_DEBUG, &resume_warn, - "Resumed reading at pts %0.3f with rate %0.3f after a lag of %0.3fs\n", - (float)pts/AV_TIME_BASE, d->readrate_catchup, (float)lag/AV_TIME_BASE); - } -@@ -2152,7 +2152,7 @@ int ifile_open(const OptionsContext *o, - d->readrate_initial_burst); - return AVERROR(EINVAL); - } -- d->readrate_catchup = o->readrate_catchup ? o->readrate_catchup : d->readrate * 1.05; -+ d->readrate_catchup = o->readrate_catchup ? o->readrate_catchup : d->readrate * 100; - if (d->readrate_catchup < d->readrate) { - av_log(d, AV_LOG_ERROR, - "Option -readrate_catchup is %0.3f; it must be at least equal to %0.3f.\n", diff --git a/debian/patches/0077-fix-readrate-catchup-caused-remuxing-to-stall.patch b/debian/patches/0077-fix-readrate-catchup-caused-remuxing-to-stall.patch new file mode 100644 index 000000000..e5eac953c --- /dev/null +++ b/debian/patches/0077-fix-readrate-catchup-caused-remuxing-to-stall.patch @@ -0,0 +1,116 @@ +Index: FFmpeg/fftools/ffmpeg_demux.c +=================================================================== +--- FFmpeg.orig/fftools/ffmpeg_demux.c ++++ FFmpeg/fftools/ffmpeg_demux.c +@@ -96,12 +96,6 @@ typedef struct DemuxStream { + uint64_t nb_packets; + // combined size of all the packets read + uint64_t data_size; +- // latest wallclock time at which packet reading resumed after a stall - used for readrate +- int64_t resume_wc; +- // timestamp of first packet sent after the latest stall - used for readrate +- int64_t resume_pts; +- // measure of how far behind packet reading is against spceified readrate +- int64_t lag; + } DemuxStream; + + typedef struct DemuxStreamGroup { +@@ -144,6 +138,13 @@ typedef struct Demuxer { + double readrate_initial_burst; + float readrate_catchup; + ++ // latest wallclock time at which packet reading resumed after a stall - used for readrate ++ int64_t resume_wc; ++ // relative timestamp of first packet sent after the latest stall - used for readrate ++ int64_t resume_progress; ++ // measure of how far behind packet reading is against spceified readrate ++ int64_t lag; ++ + Scheduler *sch; + + AVPacket *pkt_heartbeat; +@@ -514,43 +515,55 @@ static void readrate_sleep(Demuxer *d) + int64_t initial_burst = AV_TIME_BASE * d->readrate_initial_burst; + int resume_warn = 0; + ++ DemuxStream *slowest = NULL; ++ int64_t progress = INT64_MAX; ++ + for (int i = 0; i < f->nb_streams; i++) { + InputStream *ist = f->streams[i]; + DemuxStream *ds = ds_from_ist(ist); +- int64_t stream_ts_offset, pts, now, wc_elapsed, elapsed, lag, max_pts, limit_pts; +- +- if (ds->discard) continue; ++ int64_t stream_ts_offset, pts, pts_diff; ++ if (ds->discard || ds->finished || ds->first_dts == AV_NOPTS_VALUE) ++ continue; + +- stream_ts_offset = FFMAX(ds->first_dts != AV_NOPTS_VALUE ? ds->first_dts : 0, file_start); ++ stream_ts_offset = FFMAX(ds->first_dts, file_start); + pts = av_rescale(ds->dts, 1000000, AV_TIME_BASE); +- now = av_gettime_relative(); +- wc_elapsed = now - d->wallclock_start; +- +- if (pts <= stream_ts_offset + initial_burst) continue; +- +- max_pts = stream_ts_offset + initial_burst + (int64_t)(wc_elapsed * d->readrate); +- lag = FFMAX(max_pts - pts, 0); +- if ( (!ds->lag && lag > 0.3 * AV_TIME_BASE) || ( lag > ds->lag + 0.3 * AV_TIME_BASE) ) { +- ds->lag = lag; +- ds->resume_wc = now; +- ds->resume_pts = pts; +- av_log_once(ds, AV_LOG_WARNING, AV_LOG_DEBUG, &resume_warn, +- "Resumed reading at pts %0.3f with rate %0.3f after a lag of %0.3fs\n", +- (float)pts/AV_TIME_BASE, d->readrate_catchup, (float)lag/AV_TIME_BASE); +- } +- if (ds->lag && !lag) +- ds->lag = ds->resume_wc = ds->resume_pts = 0; +- if (ds->resume_wc) { +- elapsed = now - ds->resume_wc; +- limit_pts = ds->resume_pts + (int64_t)(elapsed * d->readrate_catchup); +- } else { +- elapsed = wc_elapsed; +- limit_pts = max_pts; ++ pts_diff = pts - stream_ts_offset; ++ if (pts_diff < progress) { ++ progress = pts_diff; ++ slowest = ds; + } ++ } + +- if (pts > limit_pts) +- av_usleep(pts - limit_pts); ++ if (!slowest || progress <= initial_burst) ++ return; ++ ++ int64_t now = av_gettime_relative(); ++ int64_t wc_elapsed = now - d->wallclock_start; ++ int64_t max_prog = initial_burst + (int64_t)(wc_elapsed * d->readrate); ++ int64_t lag = FFMAX(max_prog - progress, 0); ++ int64_t limit; ++ ++ if ( (!d->lag && lag > 0.3 * AV_TIME_BASE) || ( lag > d->lag + 0.3 * AV_TIME_BASE) ) { ++ d->lag = lag; ++ d->resume_wc = now; ++ d->resume_progress = progress; ++ ++ int64_t pts = FFMAX(slowest->first_dts, file_start) + progress; ++ av_log_once(slowest, AV_LOG_VERBOSE, AV_LOG_DEBUG, &resume_warn, ++ "Resumed reading at pts %0.3f with rate %0.3f after a lag of %0.3fs\n", ++ (float)pts/AV_TIME_BASE, d->readrate_catchup, (float)lag/AV_TIME_BASE); ++ } ++ if (d->lag && !lag) ++ d->lag = d->resume_wc = d->resume_progress = 0; ++ if (d->resume_wc) { ++ int64_t elapsed = now - d->resume_wc; ++ limit = d->resume_progress + (int64_t)(elapsed * d->readrate_catchup); ++ } else { ++ limit = max_prog; + } ++ ++ if (progress > limit) ++ av_usleep(progress - limit); + } + + static int do_send(Demuxer *d, DemuxStream *ds, AVPacket *pkt, unsigned flags, diff --git a/debian/patches/0083-backport-fixes-for-nvenc-and-cuvid-from-upstream.patch b/debian/patches/0083-backport-fixes-for-cuda-from-upstream.patch similarity index 56% rename from debian/patches/0083-backport-fixes-for-nvenc-and-cuvid-from-upstream.patch rename to debian/patches/0083-backport-fixes-for-cuda-from-upstream.patch index d482476ad..1599dd6d1 100644 --- a/debian/patches/0083-backport-fixes-for-nvenc-and-cuvid-from-upstream.patch +++ b/debian/patches/0083-backport-fixes-for-cuda-from-upstream.patch @@ -83,19 +83,7 @@ Index: FFmpeg/libavcodec/nvenc.c =================================================================== --- FFmpeg.orig/libavcodec/nvenc.c +++ FFmpeg/libavcodec/nvenc.c -@@ -266,8 +266,10 @@ static void nvenc_map_preset(NvencContex - - static void nvenc_print_driver_requirement(AVCodecContext *avctx, int level) - { --#if NVENCAPI_CHECK_VERSION(13, 1) -+#if NVENCAPI_CHECK_VERSION(13, 2) - const char *minver = "(unknown)"; -+#elif NVENCAPI_CHECK_VERSION(13, 1) -+ const char *minver = "610.00"; - #elif NVENCAPI_CHECK_VERSION(13, 0) - const char *minver = "570.0"; - #elif NVENCAPI_CHECK_VERSION(12, 2) -@@ -592,12 +594,24 @@ static int nvenc_check_capabilities(AVCo +@@ -594,12 +594,24 @@ static int nvenc_check_capabilities(AVCo #ifdef NVENC_HAVE_BFRAME_REF_MODE tmp = (ctx->b_ref_mode >= 0) ? ctx->b_ref_mode : NV_ENC_BFRAME_REF_MODE_DISABLED; ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_BFRAME_REF_MODE); @@ -126,7 +114,7 @@ Index: FFmpeg/libavcodec/nvenc.c } #else tmp = (ctx->b_ref_mode >= 0) ? ctx->b_ref_mode : 0; -@@ -683,7 +697,9 @@ static int nvenc_check_capabilities(AVCo +@@ -685,7 +697,9 @@ static int nvenc_check_capabilities(AVCo #ifdef NVENC_HAVE_MVHEVC ctx->multiview_supported = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_MVHEVC_ENCODE) > 0; @@ -137,7 +125,7 @@ Index: FFmpeg/libavcodec/nvenc.c av_log(avctx, AV_LOG_WARNING, "Multiview not supported by the device\n"); return AVERROR(ENOSYS); } -@@ -1163,6 +1179,13 @@ static av_cold int nvenc_setup_rate_cont +@@ -1165,6 +1179,13 @@ static av_cold int nvenc_setup_rate_cont #ifdef NVENC_HAVE_QP_CHROMA_OFFSETS ctx->encode_config.rcParams.cbQPIndexOffset = ctx->qp_cb_offset; ctx->encode_config.rcParams.crQPIndexOffset = ctx->qp_cr_offset; @@ -151,7 +139,7 @@ Index: FFmpeg/libavcodec/nvenc.c #else if (ctx->qp_cb_offset || ctx->qp_cr_offset) av_log(avctx, AV_LOG_WARNING, "Failed setting QP CB/CR offsets, SDK 11.1 or greater required at compile time.\n"); -@@ -1359,6 +1382,11 @@ static av_cold int nvenc_setup_h264_conf +@@ -1361,6 +1382,11 @@ static av_cold int nvenc_setup_h264_conf case NV_ENC_H264_PROFILE_BASELINE: cc->profileGUID = NV_ENC_H264_PROFILE_BASELINE_GUID; avctx->profile = AV_PROFILE_H264_BASELINE; @@ -163,35 +151,49 @@ Index: FFmpeg/libavcodec/nvenc.c break; case NV_ENC_H264_PROFILE_MAIN: cc->profileGUID = NV_ENC_H264_PROFILE_MAIN_GUID; -@@ -2529,7 +2557,12 @@ static void nvenc_fill_time_code(AVCodec - unsigned hh, mm, ss, ff, drop; - ff_timecode_set_smpte(&drop, &hh, &mm, &ss, &ff, avctx->framerate, tc[i + 1], 0, 0); - -+#ifdef NVENC_NEW_COUNTING_TYPE -+ time_code->clockTimestamp[i].countingTypeLSB = 0; -+ time_code->clockTimestamp[i].countingTypeMSB = 0; -+#else - time_code->clockTimestamp[i].countingType = 0; -+#endif - time_code->clockTimestamp[i].discontinuityFlag = 0; - time_code->clockTimestamp[i].cntDroppedFrames = drop; - time_code->clockTimestamp[i].nFrames = ff; -Index: FFmpeg/libavcodec/nvenc.h +Index: FFmpeg/libavfilter/vf_bwdif_cuda.cu =================================================================== ---- FFmpeg.orig/libavcodec/nvenc.h -+++ FFmpeg/libavcodec/nvenc.h -@@ -111,6 +111,11 @@ typedef void ID3D11Device; - #define NVENC_HAVE_MVHEVC - #endif +--- FFmpeg.orig/libavfilter/vf_bwdif_cuda.cu ++++ FFmpeg/libavfilter/vf_bwdif_cuda.cu +@@ -91,7 +91,7 @@ __inline__ __device__ T filter(T cur_pre + if (abs(c - e) > temporal_diff0) { + interpol = (((coef_hf[0] * (prev2_0 + next2_0) + - coef_hf[1] * (prev2_mrefs2 + next2_mrefs2 + prev2_prefs2 + next2_prefs2) +- + coef_hf[2] * (prev2_mrefs4 + next2_mrefs4 + prev2_prefs4 + next2_mrefs4)) >> 2) ++ + coef_hf[2] * (prev2_mrefs4 + next2_mrefs4 + prev2_prefs4 + next2_prefs4)) >> 2) + + coef_lf[0] * (c + e) - coef_lf[1] * (cur_mrefs3 + cur_prefs3)) >> 13; + } else { + interpol = (coef_sp[0] * (c + e) - coef_sp[1] * (cur_mrefs3 + cur_prefs3)) >> 13; +@@ -146,10 +146,10 @@ __inline__ __device__ void bwdif_single( + // Calculate temporal prediction + int is_second_field = !(parity ^ tff); -+// SDK 13.1 compile time feature checks -+#if NVENCAPI_CHECK_VERSION(13, 1) -+#define NVENC_NEW_COUNTING_TYPE -+#endif -+ - typedef struct NvencSurface - { - NV_ENC_INPUT_PTR input_surface; +- cudaTextureObject_t prev2 = prev; +- cudaTextureObject_t prev1 = is_second_field ? cur : prev; +- cudaTextureObject_t next1 = is_second_field ? next : cur; +- cudaTextureObject_t next2 = next; ++ cudaTextureObject_t prev2 = is_second_field ? cur : prev; ++ cudaTextureObject_t prev1 = prev; ++ cudaTextureObject_t next1 = next; ++ cudaTextureObject_t next2 = is_second_field ? next : cur; + + T prev2_prefs4 = tex2D(prev2, xo, yo + 4); + T prev2_prefs2 = tex2D(prev2, xo, yo + 2); +@@ -213,10 +213,10 @@ __inline__ __device__ void bwdif_double( + + int is_second_field = !(parity ^ tff); + +- cudaTextureObject_t prev2 = prev; +- cudaTextureObject_t prev1 = is_second_field ? cur : prev; +- cudaTextureObject_t next1 = is_second_field ? next : cur; +- cudaTextureObject_t next2 = next; ++ cudaTextureObject_t prev2 = is_second_field ? cur : prev; ++ cudaTextureObject_t prev1 = prev; ++ cudaTextureObject_t next1 = next; ++ cudaTextureObject_t next2 = is_second_field ? next : cur; + + T prev2_prefs4 = tex2D(prev2, xo, yo + 4); + T prev2_prefs2 = tex2D(prev2, xo, yo + 2); Index: FFmpeg/libavfilter/vf_scale_cuda.h =================================================================== --- FFmpeg.orig/libavfilter/vf_scale_cuda.h @@ -207,3 +209,87 @@ Index: FFmpeg/libavfilter/vf_scale_cuda.h #else #include #endif +Index: FFmpeg/libavfilter/vf_yadif_cuda.cu +=================================================================== +--- FFmpeg.orig/libavfilter/vf_yadif_cuda.cu ++++ FFmpeg/libavfilter/vf_yadif_cuda.cu +@@ -23,7 +23,7 @@ __inline__ __device__ T spatial_predicto + T h, T i, T j, T k, T l, T m, T n) + { + int spatial_pred = (d + k)/2; +- int spatial_score = abs(c - j) + abs(d - k) + abs(e - l); ++ int spatial_score = abs(c - j) + abs(d - k) + abs(e - l) - 1; + + int score = abs(b - k) + abs(c - l) + abs(d - m); + if (score < spatial_score) { +@@ -75,7 +75,7 @@ __inline__ __device__ T temporal_predict + int tdiff1 = (abs(A - F) + abs(B - G)) / 2; + int tdiff2 = (abs(K - F) + abs(G - L)) / 2; + +- int diff = max3(tdiff0, tdiff1, tdiff2); ++ int diff = max3(tdiff0 >> 1, tdiff1, tdiff2); + + if (!skip_check) { + int maxi = max3(p2 - p3, p2 - p1, min(p0 - p1, p4 - p3)); +@@ -85,8 +85,7 @@ __inline__ __device__ T temporal_predict + + if (spatial_pred > p2 + diff) { + spatial_pred = p2 + diff; +- } +- if (spatial_pred < p2 - diff) { ++ } else if (spatial_pred < p2 - diff) { + spatial_pred = p2 - diff; + } + +@@ -139,10 +138,10 @@ __inline__ __device__ void yadif_single( + // Calculate temporal prediction + int is_second_field = !(parity ^ tff); + +- cudaTextureObject_t prev2 = prev; +- cudaTextureObject_t prev1 = is_second_field ? cur : prev; +- cudaTextureObject_t next1 = is_second_field ? next : cur; +- cudaTextureObject_t next2 = next; ++ cudaTextureObject_t prev2 = is_second_field ? cur : prev; ++ cudaTextureObject_t prev1 = prev; ++ cudaTextureObject_t next1 = next; ++ cudaTextureObject_t next2 = is_second_field ? next : cur; + + T A = tex2D(prev2, xo, yo - 1); + T B = tex2D(prev2, xo, yo + 1); +@@ -210,10 +209,10 @@ __inline__ __device__ void yadif_double( + // Calculate temporal prediction + int is_second_field = !(parity ^ tff); + +- cudaTextureObject_t prev2 = prev; +- cudaTextureObject_t prev1 = is_second_field ? cur : prev; +- cudaTextureObject_t next1 = is_second_field ? next : cur; +- cudaTextureObject_t next2 = next; ++ cudaTextureObject_t prev2 = is_second_field ? cur : prev; ++ cudaTextureObject_t prev1 = prev; ++ cudaTextureObject_t next1 = next; ++ cudaTextureObject_t next2 = is_second_field ? next : cur; + + T A = tex2D(prev2, xo, yo - 1); + T B = tex2D(prev2, xo, yo + 1); +Index: FFmpeg/libavutil/hwcontext_cuda.c +=================================================================== +--- FFmpeg.orig/libavutil/hwcontext_cuda.c ++++ FFmpeg/libavutil/hwcontext_cuda.c +@@ -207,7 +207,7 @@ static int cuda_get_buffer(AVHWFramesCon + if (ctx->sw_format == AV_PIX_FMT_YUV420P) { + frame->linesize[1] = frame->linesize[2] = frame->linesize[0] / 2; + frame->data[2] = frame->data[1]; +- frame->data[1] = frame->data[2] + frame->linesize[2] * (ctx->height / 2); ++ frame->data[1] = frame->data[2] + frame->linesize[2] * AV_CEIL_RSHIFT(ctx->height, 1); + } + + frame->format = AV_PIX_FMT_CUDA; +@@ -259,7 +259,7 @@ static int cuda_transfer_data(AVHWFrames + .srcPitch = src->linesize[i], + .dstPitch = dst->linesize[i], + .WidthInBytes = FFMIN(src->linesize[i], dst->linesize[i]), +- .Height = src->height >> ((i == 0 || i == 3) ? 0 : priv->shift_height), ++ .Height = AV_CEIL_RSHIFT(src->height, ((i == 0 || i == 3) ? 0 : priv->shift_height)), + }; + + if (src->hw_frames_ctx) { diff --git a/debian/patches/0088-add-dtsx-detect-for-dts-hd-hra.patch b/debian/patches/0087-add-dtsx-detect-for-dts-hd-hra.patch similarity index 100% rename from debian/patches/0088-add-dtsx-detect-for-dts-hd-hra.patch rename to debian/patches/0087-add-dtsx-detect-for-dts-hd-hra.patch diff --git a/debian/patches/0087-backport-a-fix-from-upstream-for-magicyuv-decoder.patch b/debian/patches/0087-backport-a-fix-from-upstream-for-magicyuv-decoder.patch deleted file mode 100644 index 8616ccc39..000000000 --- a/debian/patches/0087-backport-a-fix-from-upstream-for-magicyuv-decoder.patch +++ /dev/null @@ -1,44 +0,0 @@ -Index: FFmpeg/libavcodec/magicyuv.c -=================================================================== ---- FFmpeg.orig/libavcodec/magicyuv.c -+++ FFmpeg/libavcodec/magicyuv.c -@@ -225,7 +225,8 @@ static int magy_decode_slice10(AVCodecCo - s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0); - dst += stride; - } -- lefttop = left = dst[0]; -+ if (1 + interlaced < height) -+ lefttop = left = dst[0]; - for (k = 1 + interlaced; k < height; k++) { - magicyuv_median_pred16(dst, dst - fake_stride, dst, width, &left, &lefttop, max); - lefttop = left = dst[0]; -@@ -584,6 +585,13 @@ static int magy_decode_frame(AVCodecCont - "invalid slice height: %d\n", s->slice_height); - return AVERROR_INVALIDDATA; - } -+ if (s->vshift[1] && (s->slice_height & ((1 << s->vshift[1]) - 1))) { -+ av_log(avctx, AV_LOG_ERROR, -+ "slice_height %d is not aligned to chroma vertical " -+ "subsampling (must be a multiple of %d)\n", -+ s->slice_height, 1 << s->vshift[1]); -+ return AVERROR_INVALIDDATA; -+ } - - bytestream2_skipu(&gb, 4); - -@@ -594,11 +602,11 @@ static int magy_decode_frame(AVCodecCont - return AVERROR_INVALIDDATA; - } - -+ if ((s->slice_height >> s->vshift[1]) <= s->interlaced) { -+ av_log(avctx, AV_LOG_ERROR, "impossible slice height\n"); -+ return AVERROR_INVALIDDATA; -+ } - if (s->interlaced) { -- if ((s->slice_height >> s->vshift[1]) < 2) { -- av_log(avctx, AV_LOG_ERROR, "impossible slice height\n"); -- return AVERROR_INVALIDDATA; -- } - if ((avctx->coded_height % s->slice_height) && ((avctx->coded_height % s->slice_height) >> s->vshift[1]) < 2) { - av_log(avctx, AV_LOG_ERROR, "impossible height\n"); - return AVERROR_INVALIDDATA; diff --git a/debian/patches/0089-add-webp-to-matroskadec-image-mime-types.patch b/debian/patches/0088-add-webp-to-matroskadec-image-mime-types.patch similarity index 100% rename from debian/patches/0089-add-webp-to-matroskadec-image-mime-types.patch rename to debian/patches/0088-add-webp-to-matroskadec-image-mime-types.patch diff --git a/debian/patches/0090-relax-to-allow-safe-filenames-in-mkv-attachments.patch b/debian/patches/0089-relax-to-allow-safe-filenames-in-mkv-attachments.patch similarity index 53% rename from debian/patches/0090-relax-to-allow-safe-filenames-in-mkv-attachments.patch rename to debian/patches/0089-relax-to-allow-safe-filenames-in-mkv-attachments.patch index bc43bd30b..5f709ccee 100644 --- a/debian/patches/0090-relax-to-allow-safe-filenames-in-mkv-attachments.patch +++ b/debian/patches/0089-relax-to-allow-safe-filenames-in-mkv-attachments.patch @@ -2,7 +2,35 @@ Index: FFmpeg/fftools/ffmpeg_demux.c =================================================================== --- FFmpeg.orig/fftools/ffmpeg_demux.c +++ FFmpeg/fftools/ffmpeg_demux.c -@@ -1789,18 +1789,21 @@ static int safe_filename(const char *f, +@@ -1757,10 +1757,26 @@ static int is_windows_reserved_device_na + { + #if HAVE_DOS_PATHS + for (const char *p = f; p && *p; ) { +- char stem[6], *s; ++ char stem[16], *s; ++ size_t len; + av_strlcpy(stem, p, sizeof(stem)); ++ ++ if ((s = strchr(stem, '/'))) ++ *s = 0; ++ ++ /* Trim trailing spaces and dots */ ++ len = strlen(stem); ++ while (len > 0 && (stem[len - 1] == ' ' || stem[len - 1] == '.')) ++ stem[--len] = 0; ++ + if ((s = strchr(stem, '.'))) + *s = 0; ++ ++ /* Trim again after stripping extension */ ++ len = strlen(stem); ++ while (len > 0 && (stem[len - 1] == ' ' || stem[len - 1] == '.')) ++ stem[--len] = 0; ++ + if ((s = strpbrk(stem, "123456789"))) + *s = '1'; + +@@ -1789,18 +1805,35 @@ static int safe_filename(const char *f, return 0; for (; *f; f++) { @@ -10,10 +38,6 @@ Index: FFmpeg/fftools/ffmpeg_demux.c - if (!((unsigned)((*f | 32) - 'a') < 26 || - (unsigned)(*f - '0') < 10 || *f == '_' || *f == '-')) { - if (f == start) -- return 0; -- else if (allow_subdir && *f == '/') -- start = f + 1; -- else if (*f != '.') + /* Non-ASCII bytes cannot be '/' or '.' */ + if ((unsigned char)*f > 127) + continue; @@ -23,17 +47,34 @@ Index: FFmpeg/fftools/ffmpeg_demux.c + if (*f == '/') { + if (!allow_subdir || f == start) return 0; +- else if (allow_subdir && *f == '/') +- start = f + 1; +- else if (*f != '.') ++ ++#if HAVE_DOS_PATHS ++ /* Reject intermediate dirs ending with trailing spaces or dots */ ++ if (f > start && (*(f - 1) == ' ' || *(f - 1) == '.')) + return 0; ++#endif ++ + start = f + 1; + } else if (*f == '.' && f == start) { + return 0; } } - return 1; ++ ++#if HAVE_DOS_PATHS ++ /* Reject final filenames ending with trailing spaces or dots */ ++ if (f > start && (*(f - 1) == ' ' || *(f - 1) == '.')) ++ return 0; ++#endif ++ + return f != start; } static int dump_attachment(InputStream *ist, const char *filename) -@@ -1817,8 +1820,8 @@ static int dump_attachment(InputStream * +@@ -1817,8 +1850,8 @@ static int dump_attachment(InputStream * if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0))) { filename = e->value; if (!safe_filename(filename, 0)) { diff --git a/debian/patches/0091-backport-a-fix-to-use-sw-pix-fmt-in-codec-par-if-set.patch b/debian/patches/0090-backport-a-fix-to-use-sw-pix-fmt-in-codec-par-if-set.patch similarity index 66% rename from debian/patches/0091-backport-a-fix-to-use-sw-pix-fmt-in-codec-par-if-set.patch rename to debian/patches/0090-backport-a-fix-to-use-sw-pix-fmt-in-codec-par-if-set.patch index af7e1506f..3aa973bd9 100644 --- a/debian/patches/0091-backport-a-fix-to-use-sw-pix-fmt-in-codec-par-if-set.patch +++ b/debian/patches/0090-backport-a-fix-to-use-sw-pix-fmt-in-codec-par-if-set.patch @@ -12,11 +12,3 @@ Index: FFmpeg/libavcodec/codec_par.c par->width = codec->width; par->height = codec->height; par->field_order = codec->field_order; -@@ -219,6 +220,7 @@ int avcodec_parameters_to_context(AVCode - - switch (par->codec_type) { - case AVMEDIA_TYPE_VIDEO: -+ codec->sw_pix_fmt = - codec->pix_fmt = par->format; - codec->width = par->width; - codec->height = par->height; diff --git a/debian/patches/0092-backport-fixes-by-comparing-n8-1-1-and-release-8-1.patch b/debian/patches/0092-backport-fixes-by-comparing-n8-1-1-and-release-8-1.patch deleted file mode 100644 index 1e280fe5e..000000000 --- a/debian/patches/0092-backport-fixes-by-comparing-n8-1-1-and-release-8-1.patch +++ /dev/null @@ -1,764 +0,0 @@ -Index: FFmpeg/libavcodec/aarch64/vp9lpf_16bpp_neon.S -=================================================================== ---- FFmpeg.orig/libavcodec/aarch64/vp9lpf_16bpp_neon.S -+++ FFmpeg/libavcodec/aarch64/vp9lpf_16bpp_neon.S -@@ -56,9 +56,7 @@ - mov x11, v4.d[0] - mov x12, v4.d[1] - adds x11, x11, x12 -- b.ne 1f -- ret x10 --1: -+ b.eq 9f - - .if \wd >= 8 - dup v0.8h, w5 -@@ -189,13 +187,7 @@ - // If no pixels need flat8in, jump to flat8out - // (or to a writeout of the inner 4 pixels, for wd=8) - .if \wd >= 8 --.if \wd == 16 - b.eq 6f --.else -- b.ne 1f -- ret x13 --1: --.endif - - // flat8in - add \tmp1\().8h, v20.8h, v21.8h -@@ -249,20 +241,16 @@ - mov x11, v2.d[0] - mov x12, v2.d[1] - adds x11, x11, x12 -- b.ne 1f - // If no pixels needed flat8in nor flat8out, jump to a - // writeout of the inner 4 pixels -- ret x14 --1: -+ b.eq 7f - - mov x11, v7.d[0] - mov x12, v7.d[1] - adds x11, x11, x12 -- b.ne 1f - // If no pixels need flat8out, jump to a writeout of the inner 6 pixels -- ret x15 -+ b.eq 8f - --1: - // flat8out - // This writes all outputs into v2-v17 (skipping v6 and v16). - // If this part is skipped, the output is read from v21-v26 (which is the input -@@ -378,35 +366,57 @@ - // while we need those for inputs/outputs in wd=16 and use v8-v15 - // for temp registers there instead. - function vp9_loop_filter_4 -+ mov x13, #0 - loop_filter 4, v16, v17, v18, v19, v28, v29, v30, v31 - ret -+9: -+ mov x13, #(1<<9) -+ ret - endfunc - - function vp9_loop_filter_8 -+ mov x13, #0 - loop_filter 8, v16, v17, v18, v19, v28, v29, v30, v31 - ret -+6: -+ mov x13, #(1<<6) -+ ret -+9: -+ mov x13, #(1<<9) -+ ret - endfunc - - function vp9_loop_filter_16 -+ mov x13, #0 - loop_filter 16, v8, v9, v10, v11, v12, v13, v14, v15 - ret -+7: -+ mov x13, #(1<<7) -+ ret -+8: -+ mov x13, #(1<<8) -+ ret -+9: -+ mov x13, #(1<<9) -+ ret - endfunc - - .macro loop_filter_4 - bl vp9_loop_filter_4 -+ tbnz x13, #9, 9f - .endm - - .macro loop_filter_8 -- // calculate alternative 'return' targets -- adr x13, 6f - bl vp9_loop_filter_8 -+ tbnz x13, #6, 6f -+ tbnz x13, #9, 9f - .endm - - .macro loop_filter_16 -- // calculate alternative 'return' targets -- adr x14, 7f -- adr x15, 8f - bl vp9_loop_filter_16 -+ tbnz x13, #7, 7f -+ tbnz x13, #8, 8f -+ tbnz x13, #9, 9f - .endm - - -@@ -540,7 +550,7 @@ function vp9_loop_filter_v_4_8_16_neon - st1 {v23.8h}, [x9], x1 - st1 {v25.8h}, [x0], x1 - sub x0, x0, x1, lsl #1 -- -+9: - ret x10 - endfunc - -@@ -588,7 +598,7 @@ function vp9_loop_filter_h_4_8_16_neon - st1 {v25.d}[1], [x0], x1 - sub x0, x0, x1, lsl #3 - add x0, x0, #4 -- -+9: - ret x10 - endfunc - -@@ -619,7 +629,7 @@ function vp9_loop_filter_v_8_8_16_neon - st1 {v26.8h}, [x0], x1 - sub x0, x0, x1, lsl #1 - sub x0, x0, x1 -- -+9: - ret x10 - 6: - sub x9, x0, x1, lsl #1 -@@ -670,7 +680,7 @@ function vp9_loop_filter_h_8_8_16_neon - st1 {v27.8h}, [x0], x1 - sub x0, x0, x1, lsl #3 - add x0, x0, #8 -- -+9: - ret x10 - 6: - // If we didn't need to do the flat8in part, we use the same writeback -@@ -742,7 +752,7 @@ function vp9_loop_filter_v_16_8_16_neon - st1 {v17.8h}, [x0], x1 - sub x0, x0, x1, lsl #3 - add x0, x0, x1 -- -+9: - ret x10 - 8: - add x9, x9, x1, lsl #2 -@@ -820,7 +830,7 @@ function vp9_loop_filter_h_16_8_16_neon - st1 {v9.8h}, [x9], x1 - st1 {v31.8h}, [x0], x1 - sub x0, x0, x1, lsl #3 -- -+9: - ret x10 - 8: - // The same writeback as in loop_filter_h_8_8 -Index: FFmpeg/libavcodec/aarch64/vp9lpf_neon.S -=================================================================== ---- FFmpeg.orig/libavcodec/aarch64/vp9lpf_neon.S -+++ FFmpeg/libavcodec/aarch64/vp9lpf_neon.S -@@ -388,32 +388,28 @@ - .endif - .if \wd == 16 - 6: -+ // If no pixels needed flat8in nor flat8out, jump to a -+ // writeout of the inner 4 pixels - orr v2\sz, v6\sz, v7\sz - mov x5, v2.d[0] - .ifc \sz, .16b - mov x6, v2.d[1] - adds x5, x5, x6 -- b.ne 1f -+ b.eq 7f - .else -- cbnz x5, 1f -+ cbz x5, 7f - .endif -- // If no pixels needed flat8in nor flat8out, jump to a -- // writeout of the inner 4 pixels -- ret x14 --1: - -+ // If no pixels need flat8out, jump to a writeout of the inner 6 pixels - mov x5, v7.d[0] - .ifc \sz, .16b - mov x6, v7.d[1] - adds x5, x5, x6 -- b.ne 1f -+ b.eq 8f - .else -- cbnz x5, 1f -+ cbz x5, 8f - .endif -- // If no pixels need flat8out, jump to a writeout of the inner 6 pixels -- ret x15 - --1: - // flat8out - // This writes all outputs into v2-v17 (skipping v6 and v16). - // If this part is skipped, the output is read from v21-v26 (which is the input -@@ -529,76 +525,94 @@ - // while we need those for inputs/outputs in wd=16 and use v8-v15 - // for temp registers there instead. - function vp9_loop_filter_4 -+ mov x13, #0 - loop_filter 4, .8b, 0, v16, v17, v18, v19, v28, v29, v30, v31 - ret - 9: -- ret x10 -+ mov x13, #(1<<9) -+ ret - endfunc - - function vp9_loop_filter_4_16b_mix_44 -+ mov x13, #0 - loop_filter 4, .16b, 44, v16, v17, v18, v19, v28, v29, v30, v31 - ret - 9: -- ret x10 -+ mov x13, #(1<<9) -+ ret - endfunc - - function vp9_loop_filter_8 -+ mov x13, #0 - loop_filter 8, .8b, 0, v16, v17, v18, v19, v28, v29, v30, v31 - ret - 6: -- ret x13 -+ mov x13, #(1<<6) -+ ret - 9: -- ret x10 -+ mov x13, #(1<<9) -+ ret - endfunc - - function vp9_loop_filter_8_16b_mix -+ mov x13, #0 - loop_filter 8, .16b, 88, v16, v17, v18, v19, v28, v29, v30, v31 - ret - 6: -- ret x13 -+ mov x13, #(1<<6) -+ ret - 9: -- ret x10 -+ mov x13, #(1<<9) -+ ret - endfunc - - function vp9_loop_filter_16 -+ mov x13, #0 - loop_filter 16, .8b, 0, v8, v9, v10, v11, v12, v13, v14, v15 - ret -+7: -+ mov x13, #(1<<7) -+ ret -+8: -+ mov x13, #(1<<8) -+ ret - 9: -- ldp d10, d11, [sp, #0x10] -- ldp d12, d13, [sp, #0x20] -- ldp d14, d15, [sp, #0x30] -- ldp d8, d9, [sp], #0x40 -- ret x10 -+ mov x13, #(1<<9) -+ ret - endfunc - - function vp9_loop_filter_16_16b -+ mov x13, #0 - loop_filter 16, .16b, 0, v8, v9, v10, v11, v12, v13, v14, v15 - ret -+7: -+ mov x13, #(1<<7) -+ ret -+8: -+ mov x13, #(1<<8) -+ ret - 9: -- ldp d10, d11, [sp, #0x10] -- ldp d12, d13, [sp, #0x20] -- ldp d14, d15, [sp, #0x30] -- ldp d8, d9, [sp], #0x40 -- ret x10 -+ mov x13, #(1<<9) -+ ret - endfunc - - .macro loop_filter_4 - bl vp9_loop_filter_4 -+ tbnz x13, #9, 9f - .endm - - .macro loop_filter_4_16b_mix mix - bl vp9_loop_filter_4_16b_mix_\mix -+ tbnz x13, #9, 9f - .endm - - .macro loop_filter_8 -- // calculate alternative 'return' targets -- adr x13, 6f - bl vp9_loop_filter_8 -+ tbnz x13, #6, 6f -+ tbnz x13, #9, 9f - .endm - - .macro loop_filter_8_16b_mix mix -- // calculate alternative 'return' targets -- adr x13, 6f - .if \mix == 48 - mov x11, #0xffffffff00000000 - .elseif \mix == 84 -@@ -607,20 +621,22 @@ endfunc - mov x11, #0xffffffffffffffff - .endif - bl vp9_loop_filter_8_16b_mix -+ tbnz x13, #6, 6f -+ tbnz x13, #9, 9f - .endm - - .macro loop_filter_16 -- // calculate alternative 'return' targets -- adr x14, 7f -- adr x15, 8f - bl vp9_loop_filter_16 -+ tbnz x13, #7, 7f -+ tbnz x13, #8, 8f -+ tbnz x13, #9, 9f - .endm - - .macro loop_filter_16_16b -- // calculate alternative 'return' targets -- adr x14, 7f -- adr x15, 8f - bl vp9_loop_filter_16_16b -+ tbnz x13, #7, 7f -+ tbnz x13, #8, 8f -+ tbnz x13, #9, 9f - .endm - - -@@ -647,7 +663,7 @@ function ff_vp9_loop_filter_v_4_8_neon, - st1 {v24.8b}, [x0], x1 - st1 {v23.8b}, [x9], x1 - st1 {v25.8b}, [x0], x1 -- -+9: - ret x10 - endfunc - -@@ -671,7 +687,7 @@ function ff_vp9_loop_filter_v_44_16_neon - st1 {v24.16b}, [x0], x1 - st1 {v23.16b}, [x9], x1 - st1 {v25.16b}, [x0], x1 -- -+9: - ret x10 - endfunc - -@@ -713,7 +729,7 @@ function ff_vp9_loop_filter_h_4_8_neon, - st1 {v24.s}[1], [x0], x1 - st1 {v25.s}[0], [x9], x1 - st1 {v25.s}[1], [x0], x1 -- -+9: - ret x10 - endfunc - -@@ -765,7 +781,7 @@ function ff_vp9_loop_filter_h_44_16_neon - st1 {v24.s}[3], [x0], x1 - st1 {v25.s}[1], [x9], x1 - st1 {v25.s}[3], [x0], x1 -- -+9: - ret x10 - endfunc - -@@ -792,7 +808,7 @@ function ff_vp9_loop_filter_v_8_8_neon, - st1 {v25.8b}, [x0], x1 - st1 {v23.8b}, [x9], x1 - st1 {v26.8b}, [x0], x1 -- -+9: - ret x10 - 6: - sub x9, x0, x1, lsl #1 -@@ -827,7 +843,7 @@ function ff_vp9_loop_filter_v_\mix\()_16 - st1 {v25.16b}, [x0], x1 - st1 {v23.16b}, [x9], x1 - st1 {v26.16b}, [x0], x1 -- -+9: - ret x10 - 6: - sub x9, x0, x1, lsl #1 -@@ -875,7 +891,7 @@ function ff_vp9_loop_filter_h_8_8_neon, - st1 {v26.8b}, [x0], x1 - st1 {v23.8b}, [x9], x1 - st1 {v27.8b}, [x0], x1 -- -+9: - ret x10 - 6: - // If we didn't need to do the flat8in part, we use the same writeback -@@ -941,7 +957,7 @@ function ff_vp9_loop_filter_h_\mix\()_16 - st1 {v26.d}[1], [x0], x1 - st1 {v27.8b}, [x9], x1 - st1 {v27.d}[1], [x0], x1 -- -+9: - ret x10 - 6: - add x9, x9, #2 -Index: FFmpeg/libavcodec/vulkan_encode.c -=================================================================== ---- FFmpeg.orig/libavcodec/vulkan_encode.c -+++ FFmpeg/libavcodec/vulkan_encode.c -@@ -772,14 +772,6 @@ av_cold int ff_vulkan_encode_init(AVCode - return AVERROR(EINVAL); - } - -- if ((ctx->enc_caps.supportedEncodeFeedbackFlags & feedback_flags) != -- feedback_flags) { -- av_log (avctx, AV_LOG_ERROR, -- "Driver does not support required encode feedback flags " -- "(BUFFER_OFFSET and BYTES_WRITTEN).\n"); -- return AVERROR(ENOTSUP); -- } -- - ctx->base.op = &vulkan_base_encode_ops; - ctx->codec = codec; - -@@ -881,6 +873,14 @@ av_cold int ff_vulkan_encode_init(AVCode - return AVERROR_EXTERNAL; - } - -+ if ((ctx->enc_caps.supportedEncodeFeedbackFlags & feedback_flags) != -+ feedback_flags) { -+ av_log(avctx, AV_LOG_ERROR, -+ "Driver does not support required encode feedback flags " -+ "(BUFFER_OFFSET and BYTES_WRITTEN).\n"); -+ return AVERROR(ENOTSUP); -+ } -+ - err = init_rc(avctx, ctx); - if (err < 0) - return err; -Index: FFmpeg/libavformat/dashdec.c -=================================================================== ---- FFmpeg.orig/libavformat/dashdec.c -+++ FFmpeg/libavformat/dashdec.c -@@ -447,7 +447,7 @@ static int open_url(AVFormatContext *s, - av_freep(pb); - av_dict_copy(&tmp, *opts, 0); - av_dict_copy(&tmp, opts2, 0); -- ret = ffio_open_whitelist(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp, s->protocol_whitelist, s->protocol_blacklist); -+ ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); - if (ret >= 0) { - // update cookies on http response with setcookies. - char *new_cookies = NULL; -@@ -1255,7 +1255,7 @@ static int parse_manifest(AVFormatContex - close_in = 1; - - av_dict_copy(&opts, c->avio_opts, 0); -- ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ, c->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist); -+ ret = s->io_open(s, &in, url, AVIO_FLAG_READ, &opts); - av_dict_free(&opts); - if (ret < 0) - return ret; -@@ -1398,7 +1398,7 @@ cleanup: - - av_bprint_finalize(&buf, NULL); - if (close_in) { -- avio_close(in); -+ ff_format_io_close(s, &in); - } - return ret; - } -Index: FFmpeg/libavformat/dashenc.c -=================================================================== ---- FFmpeg.orig/libavformat/dashenc.c -+++ FFmpeg/libavformat/dashenc.c -@@ -490,7 +490,7 @@ static void dash_free(AVFormatContext *s - if (!c->single_file) - ffio_free_dyn_buf(&os->ctx->pb); - else -- avio_close(os->ctx->pb); -+ ff_format_io_close(s, &os->ctx->pb); - } - ff_format_io_close(s, &os->out); - avformat_free_context(os->ctx); -@@ -1458,7 +1458,7 @@ static int dash_init(AVFormatContext *s) - ret = s->io_open(s, &os->out, filename, AVIO_FLAG_WRITE, &opts); - } else { - ctx->url = av_strdup(filename); -- ret = avio_open2(&ctx->pb, filename, AVIO_FLAG_WRITE, NULL, &opts); -+ ret = s->io_open(s, &ctx->pb, filename, AVIO_FLAG_WRITE, &opts); - } - av_dict_free(&opts); - if (ret < 0) -Index: FFmpeg/libavformat/demux.c -=================================================================== ---- FFmpeg.orig/libavformat/demux.c -+++ FFmpeg/libavformat/demux.c -@@ -368,7 +368,7 @@ fail: - ff_id3v2_free_extra_meta(&id3v2_extra_meta); - av_dict_free(&tmp); - if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO)) -- avio_closep(&s->pb); -+ ff_format_io_close(s, &s->pb); - avformat_free_context(s); - *ps = NULL; - return ret; -Index: FFmpeg/libavformat/hlsenc.c -=================================================================== ---- FFmpeg.orig/libavformat/hlsenc.c -+++ FFmpeg/libavformat/hlsenc.c -@@ -703,7 +703,7 @@ static int do_encrypt(AVFormatContext *s - return ret; - avio_seek(pb, 0, SEEK_CUR); - avio_write(pb, key, KEYSIZE); -- avio_close(pb); -+ ff_format_io_close(s, &pb); - } - return 0; - } -@@ -1171,9 +1171,7 @@ static int parse_playlist(AVFormatContex - const char *end; - double discont_program_date_time = 0; - -- if ((ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ, -- &s->interrupt_callback, NULL, -- s->protocol_whitelist, s->protocol_blacklist)) < 0) -+ if ((ret = s->io_open(s, &in, url, AVIO_FLAG_READ, NULL)) < 0) - return ret; - - ff_get_chomp_line(in, line, sizeof(line)); -@@ -1283,7 +1281,7 @@ static int parse_playlist(AVFormatContex - } - - fail: -- avio_close(in); -+ ff_format_io_close(s, &in); - return ret; - } - -Index: FFmpeg/libavformat/mov.c -=================================================================== ---- FFmpeg.orig/libavformat/mov.c -+++ FFmpeg/libavformat/mov.c -@@ -1237,15 +1237,13 @@ static int mov_read_chnl(MOVContext *c, - version = avio_r8(pb); - flags = avio_rb24(pb); - if (version != 0 || flags != 0) { -- av_log(c->fc, AV_LOG_ERROR, -- "Unsupported 'chnl' box with version %d, flags: %#x", -+ av_log(c->fc, AV_LOG_WARNING, -+ "Unsupported 'chnl' box with version %d, flags: %#x\n", - version, flags); -- return AVERROR_INVALIDDATA; -+ return 0; - } - -- ret = ff_mov_read_chnl(c->fc, pb, st); -- if (ret < 0) -- return ret; -+ ff_mov_read_chnl(c->fc, pb, st); - - if (avio_tell(pb) != end) { - av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n", -Index: FFmpeg/libavformat/mov_chan.c -=================================================================== ---- FFmpeg.orig/libavformat/mov_chan.c -+++ FFmpeg/libavformat/mov_chan.c -@@ -375,6 +375,7 @@ static int mov_get_channel_layout(AVChan - /* find the channel layout for the specified layout tag */ - layout_map = find_layout_map(tag, map); - if (layout_map) { -+ AVChannelLayout tmp = { 0 }; - int ret; - int map_layout_nb_channels = tag & 0xFFFF; - int nb_channels = ch_layout->nb_channels; -@@ -383,19 +384,23 @@ static int mov_get_channel_layout(AVChan - if (omitted_channel_map >> map_layout_nb_channels) - return AVERROR_INVALIDDATA; - -- av_channel_layout_uninit(ch_layout); -- ret = av_channel_layout_custom_init(ch_layout, nb_channels); -+ ret = av_channel_layout_custom_init(&tmp, nb_channels); - if (ret < 0) - return ret; - - for (int i = 0, idx = 0; i < map_layout_nb_channels && idx < nb_channels; i++, omitted_channel_map >>= 1) { - if (!(omitted_channel_map & 1)) { - enum AVChannel id = layout_map[i].id; -- ch_layout->u.map[idx++].id = (id != AV_CHAN_NONE ? id : AV_CHAN_UNKNOWN); -+ tmp.u.map[idx++].id = (id != AV_CHAN_NONE ? id : AV_CHAN_UNKNOWN); - } - } - -- return av_channel_layout_retype(ch_layout, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL); -+ ret = av_channel_layout_retype(&tmp, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL); -+ if (ret < 0) -+ return ret; -+ -+ av_channel_layout_uninit(ch_layout); -+ *ch_layout = tmp; - } - return 0; - } -@@ -543,6 +548,7 @@ int ff_mov_read_chan(AVFormatContext *s, - return 0; - - if (layout_tag == MOV_CH_LAYOUT_USE_DESCRIPTIONS) { -+ AVChannelLayout tmp = { 0 }; - int nb_channels = ch_layout->nb_channels; - - if (!num_descr || num_descr < nb_channels) { -@@ -562,8 +568,7 @@ int ff_mov_read_chan(AVFormatContext *s, - num_descr = nb_channels; - } - -- av_channel_layout_uninit(ch_layout); -- ret = av_channel_layout_custom_init(ch_layout, nb_channels); -+ ret = av_channel_layout_custom_init(&tmp, nb_channels); - if (ret < 0) - goto out; - -@@ -580,12 +585,15 @@ int ff_mov_read_chan(AVFormatContext *s, - avio_rl32(pb); // mCoordinates[1] - avio_rl32(pb); // mCoordinates[2] - size -= 20; -- ch_layout->u.map[i].id = mov_get_channel_id(label); -+ tmp.u.map[i].id = mov_get_channel_id(label); - } - -- ret = av_channel_layout_retype(ch_layout, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL); -+ ret = av_channel_layout_retype(&tmp, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL); - if (ret < 0) - goto out; -+ -+ av_channel_layout_uninit(ch_layout); -+ *ch_layout = tmp; - } else if (layout_tag == MOV_CH_LAYOUT_USE_BITMAP) { - if (!ch_layout->nb_channels || av_popcount(bitmap) == ch_layout->nb_channels) { - if (bitmap < 0x40000) { -@@ -737,11 +745,10 @@ int ff_mov_read_chnl(AVFormatContext *s, - - av_log(s, AV_LOG_TRACE, "'chnl' layout %d\n", layout); - if (!layout) { -- AVChannelLayout *ch_layout = &st->codecpar->ch_layout; -+ AVChannelLayout tmp = { 0 }, *ch_layout = &st->codecpar->ch_layout; - int nb_channels = ch_layout->nb_channels; - -- av_channel_layout_uninit(ch_layout); -- ret = av_channel_layout_custom_init(ch_layout, nb_channels); -+ ret = av_channel_layout_custom_init(&tmp, nb_channels); - if (ret < 0) - return ret; - -@@ -762,12 +769,15 @@ int ff_mov_read_chnl(AVFormatContext *s, - channel = AV_CHAN_UNKNOWN; - } - -- ch_layout->u.map[i].id = channel; -+ tmp.u.map[i].id = channel; - } - -- ret = av_channel_layout_retype(ch_layout, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL); -+ ret = av_channel_layout_retype(&tmp, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL); - if (ret < 0) - return ret; -+ -+ av_channel_layout_uninit(ch_layout); -+ *ch_layout = tmp; - } else { - uint64_t omitted_channel_map = avio_rb64(pb); - ret = ff_mov_get_channel_layout_from_config(layout, &st->codecpar->ch_layout, omitted_channel_map); -Index: FFmpeg/libavformat/oggparsecelt.c -=================================================================== ---- FFmpeg.orig/libavformat/oggparsecelt.c -+++ FFmpeg/libavformat/oggparsecelt.c -@@ -27,6 +27,9 @@ - #include "internal.h" - #include "oggdec.h" - -+/* CELT-over-Ogg streams use at most a couple of vorbiscomment "extra" headers. */ -+#define CELT_MAX_EXTRA_HEADERS 16 -+ - struct oggcelt_private { - int extra_headers_left; - }; -@@ -62,6 +65,12 @@ static int celt_header(AVFormatContext * - overlap = AV_RL32(p + 48); - /* unused bytes per packet field skipped */ - extra_headers = AV_RL32(p + 56); -+ if (extra_headers > CELT_MAX_EXTRA_HEADERS) { -+ av_log(s, AV_LOG_ERROR, -+ "Too many CELT extra headers (%u)\n", extra_headers); -+ av_free(priv); -+ return AVERROR_INVALIDDATA; -+ } - st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; - st->codecpar->codec_id = AV_CODEC_ID_CELT; - st->codecpar->sample_rate = sample_rate; -Index: FFmpeg/libavformat/oggparsevorbis.c -=================================================================== ---- FFmpeg.orig/libavformat/oggparsevorbis.c -+++ FFmpeg/libavformat/oggparsevorbis.c -@@ -230,8 +230,11 @@ static int fixup_vorbis_headers(AVFormat - int i, offset, len, err; - int buf_len; - unsigned char *ptr; -+ uint64_t total_len = (uint64_t)priv->len[0] + priv->len[1] + priv->len[2]; -+ if (total_len + total_len / 255 + 64 > INT_MAX) -+ return AVERROR_INVALIDDATA; - -- len = priv->len[0] + priv->len[1] + priv->len[2]; -+ len = total_len; - buf_len = len + len / 255 + 64; - - if (*buf) -Index: FFmpeg/libavformat/rtpdec_av1.c -=================================================================== ---- FFmpeg.orig/libavformat/rtpdec_av1.c -+++ FFmpeg/libavformat/rtpdec_av1.c -@@ -249,7 +249,7 @@ static int av1_handle_packet(AVFormatCon - // ignore and remove OBUs according to spec - if ((obu_type == AV1_OBU_TEMPORAL_DELIMITER) || - (obu_type == AV1_OBU_TILE_LIST)) { -- pktpos += obu_size; -+ buf_ptr += obu_size; - rem_pkt_size -= obu_size; - // TODO: This probably breaks if the OBU_TILE_LIST is fragmented - // into the next RTP packet, so at least check and fail here -Index: FFmpeg/libavformat/version.h -=================================================================== ---- FFmpeg.orig/libavformat/version.h -+++ FFmpeg/libavformat/version.h -@@ -32,7 +32,7 @@ - #include "version_major.h" - - #define LIBAVFORMAT_VERSION_MINOR 12 --#define LIBAVFORMAT_VERSION_MICRO 101 -+#define LIBAVFORMAT_VERSION_MICRO 102 - - #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ - LIBAVFORMAT_VERSION_MINOR, \ diff --git a/debian/patches/series b/debian/patches/series index 20d475059..448f6ffd4 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -74,19 +74,17 @@ 0074-fix-mapped-hwframe-to-swframe-swscale-conversion.patch 0075-fix-hwupload-filter-cannot-use-devices-created-by-hwaccel.patch 0076-fix-seeking-h264-open-gop-videos-with-d3d11va-on-amd.patch -0077-fix-low-default-readrate-catchup-caused-remuxing-to-stall.patch +0077-fix-readrate-catchup-caused-remuxing-to-stall.patch 0078-backport-fixes-for-vulkan-from-upstream.patch 0079-add-fixes-for-vaapi-drm-prime-vulkan-interop.patch 0080-prefer-vulkan-device-with-higher-api-version.patch 0081-signal-vulkan-semaphores-in-drm-prime-reverse-mapping.patch 0082-add-fixes-and-enhancements-for-vulkan-filters.patch -0083-backport-fixes-for-nvenc-and-cuvid-from-upstream.patch +0083-backport-fixes-for-cuda-from-upstream.patch 0084-backport-fixes-for-detecting-ac4-streams-in-mpegts.patch 0085-fix-hdr10-sidedata-not-removed-in-libplacebo-outlink.patch 0086-workaround-amd-hevc-vaapi-encoder-out-of-band-vtag-hvc1.patch -0087-backport-a-fix-from-upstream-for-magicyuv-decoder.patch -0088-add-dtsx-detect-for-dts-hd-hra.patch -0089-add-webp-to-matroskadec-image-mime-types.patch -0090-relax-to-allow-safe-filenames-in-mkv-attachments.patch -0091-backport-a-fix-to-use-sw-pix-fmt-in-codec-par-if-set.patch -0092-backport-fixes-by-comparing-n8-1-1-and-release-8-1.patch +0087-add-dtsx-detect-for-dts-hd-hra.patch +0088-add-webp-to-matroskadec-image-mime-types.patch +0089-relax-to-allow-safe-filenames-in-mkv-attachments.patch +0090-backport-a-fix-to-use-sw-pix-fmt-in-codec-par-if-set.patch diff --git a/doc/Doxyfile b/doc/Doxyfile index 9e0842539..9c388d7e5 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = FFmpeg # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 8.1.1 +PROJECT_NUMBER = 8.1.2 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/docker-build-win64.sh b/docker-build-win64.sh index f13d01526..3e034e102 100755 --- a/docker-build-win64.sh +++ b/docker-build-win64.sh @@ -179,7 +179,7 @@ ninja -j$(nproc) -C fontconfig_build install popd # HARFBUZZ -git clone -b 14.2.0 --depth=1 https://github.com/harfbuzz/harfbuzz.git +git clone -b 14.2.1 --depth=1 https://github.com/harfbuzz/harfbuzz.git meson setup harfbuzz harfbuzz_build \ --prefix=${FF_DEPS_PREFIX} \ --cross-file=${FF_MESON_TOOLCHAIN} \ @@ -218,7 +218,7 @@ make install popd # LIBASS -git clone -b 0.17.4 --depth=1 https://github.com/libass/libass.git +git clone -b 0.17.5 --depth=1 https://github.com/libass/libass.git pushd libass ./autogen.sh ./configure \ @@ -321,7 +321,7 @@ popd # OPENMPT mkdir mpt pushd mpt -mpt_ver="0.8.6" +mpt_ver="0.8.7" mpt_link="https://lib.openmpt.org/files/libopenmpt/src/libopenmpt-${mpt_ver}+release.autotools.tar.gz" wget ${mpt_link} -O mpt.tar.gz tar xaf mpt.tar.gz @@ -549,7 +549,7 @@ popd # AMF mkdir amf-headers pushd amf-headers -amf_ver="1.5.0" +amf_ver="1.5.2" amf_link="https://github.com/GPUOpen-LibrariesAndSDKs/AMF/releases/download/v${amf_ver}/AMF-headers-v${amf_ver}.tar.gz" wget ${amf_link} -O amf.tar.gz tar xaf amf.tar.gz @@ -560,7 +560,7 @@ popd popd # VPL -git clone -b v2.16.0 --depth=1 https://github.com/intel/libvpl.git +git clone -b v2.17.0 --depth=1 https://github.com/intel/libvpl.git pushd libvpl mkdir build && pushd build cmake \ @@ -571,6 +571,7 @@ cmake \ -DCMAKE_BUILD_TYPE=Release \ -DBUILD_SHARED_LIBS=OFF \ -DINSTALL_{DEV,LIB}=ON \ + -DINSTALL_EXAMPLES=OFF \ -DBUILD_{TESTS,EXAMPLES,EXPERIMENTAL}=OFF \ .. make -j$(nproc) diff --git a/docker-build.sh b/docker-build.sh index 6239d0f5c..bca2b6fb2 100755 --- a/docker-build.sh +++ b/docker-build.sh @@ -135,7 +135,7 @@ prepare_extra_common() { # HARFBUZZ pushd ${SOURCE_DIR} - git clone -b 14.2.0 --depth=1 https://github.com/harfbuzz/harfbuzz.git + git clone -b 14.2.1 --depth=1 https://github.com/harfbuzz/harfbuzz.git meson setup harfbuzz harfbuzz_build \ ${MESON_CROSS_OPT} \ --prefix=${TARGET_DIR} \ @@ -169,7 +169,7 @@ prepare_extra_common() { # LIBASS pushd ${SOURCE_DIR} - git clone -b 0.17.4 --depth=1 https://github.com/libass/libass.git + git clone -b 0.17.5 --depth=1 https://github.com/libass/libass.git pushd libass ./autogen.sh ./configure \ @@ -315,7 +315,7 @@ prepare_extra_amd64() { pushd ${SOURCE_DIR} mkdir amf-headers pushd amf-headers - amf_ver="1.5.0" + amf_ver="1.5.2" amf_link="https://github.com/GPUOpen-LibrariesAndSDKs/AMF/releases/download/v${amf_ver}/AMF-headers-v${amf_ver}.tar.gz" wget ${amf_link} -O amf.tar.gz tar xaf amf.tar.gz @@ -431,7 +431,7 @@ prepare_extra_amd64() { # Provides VPL header and dispatcher (libvpl.so.2) for FFmpeg # Both MSDK and VPL runtime can be loaded by VPL dispatcher pushd ${SOURCE_DIR} - git clone -b v2.16.0 --depth=1 https://github.com/intel/libvpl.git + git clone -b v2.17.0 --depth=1 https://github.com/intel/libvpl.git pushd libvpl sed -i 's|ParseEnvSearchPaths(ONEVPL_PRIORITY_PATH_VAR, searchDirList)|searchDirList.push_back("/usr/lib/jellyfin-ffmpeg/lib")|g' libvpl/src/mfx_dispatcher_vpl_loader.cpp mkdir build && pushd build @@ -441,6 +441,7 @@ prepare_extra_amd64() { -DCMAKE_BUILD_TYPE=Release \ -DBUILD_SHARED_LIBS=ON \ -DINSTALL_{DEV,LIB}=ON \ + -DINSTALL_EXAMPLES=OFF \ -DBUILD_{TESTS,EXAMPLES,EXPERIMENTAL}=OFF \ .. make -j$(nproc) && make install && make install DESTDIR=${SOURCE_DIR}/intel @@ -453,7 +454,7 @@ prepare_extra_amd64() { # VPL-GPU-RT (RT only) # Provides VPL runtime (libmfx-gen.so.1.2) for 11th Gen Tiger Lake and newer pushd ${SOURCE_DIR} - git clone -b intel-onevpl-26.1.6 --depth=1 https://github.com/intel/vpl-gpu-rt.git + git clone -b intel-onevpl-26.2.3 --depth=1 https://github.com/intel/vpl-gpu-rt.git pushd vpl-gpu-rt # Fix missing entries in PicStruct validation wget -q -O - https://github.com/intel/vpl-gpu-rt/commit/c7eb030.patch | git apply @@ -475,10 +476,12 @@ prepare_extra_amd64() { # Full Feature Build: ENABLE_KERNELS=ON(Default) ENABLE_NONFREE_KERNELS=ON(Default) # Free Kernel Build: ENABLE_KERNELS=ON ENABLE_NONFREE_KERNELS=OFF pushd ${SOURCE_DIR} - git clone -b intel-media-26.1.6 --depth=1 https://github.com/intel/media-driver.git + git clone -b intel-media-26.2.3 --depth=1 https://github.com/intel/media-driver.git pushd media-driver # Enable VC1 decode on DG2 (note that MTL+ is not supported) - wget -q -O - https://github.com/intel/media-driver/commit/25fb926.patch | git apply + wget -q -O - https://github.com/intel/media-driver/commit/e47702f.patch | git apply + # Fix iHD crashes when used with Xe KMD on small BAR systems + wget -q -O - https://github.com/intel/media-driver/commit/6fd4037.patch | git apply mkdir build && pushd build cmake -DCMAKE_INSTALL_PREFIX=${TARGET_DIR} \ -DCMAKE_C_FLAGS="${CFLAGS} -Wno-error=array-bounds" \ @@ -498,7 +501,7 @@ prepare_extra_amd64() { # Vulkan Headers pushd ${SOURCE_DIR} - git clone -b v1.4.349 --depth=1 https://github.com/KhronosGroup/Vulkan-Headers.git + git clone -b v1.4.355 --depth=1 https://github.com/KhronosGroup/Vulkan-Headers.git pushd Vulkan-Headers mkdir build && pushd build cmake \ @@ -511,7 +514,7 @@ prepare_extra_amd64() { # Vulkan ICD Loader pushd ${SOURCE_DIR} - git clone -b v1.4.349 --depth=1 https://github.com/KhronosGroup/Vulkan-Loader.git + git clone -b v1.4.355 --depth=1 https://github.com/KhronosGroup/Vulkan-Loader.git pushd Vulkan-Loader mkdir build && pushd build cmake \ @@ -531,7 +534,7 @@ prepare_extra_amd64() { popd # SHADERC - shaderc_ver="v2026.1" + shaderc_ver="v2026.2" pushd ${SOURCE_DIR} git clone -b ${shaderc_ver} --depth=1 https://github.com/google/shaderc.git pushd shaderc @@ -578,6 +581,12 @@ prepare_extra_amd64() { # Enable VAAPI VPP alpha blending support wget -q -O - https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41090.patch | \ patch -p1 -d mesa-${mesa_ver} + # Fix misc CSC issues in VAAPI VPP + wget -q -O - https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42181.patch | \ + patch -p1 -d mesa-${mesa_ver} + # Fix setting VPE rotation with horizontal flip enabled + wget -q -O - https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42408.patch | \ + sed 's#/mm/#/#g' | patch -p1 -d mesa-${mesa_ver} meson setup mesa-${mesa_ver} mesa_build \ --prefix=${TARGET_DIR} \ --libdir=lib \ diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index b4d3a2c2a..3e3343817 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -469,7 +469,7 @@ typedef struct Decoder { enum AVMediaType type; - const uint8_t *subtitle_header; + uint8_t *subtitle_header; int subtitle_header_size; // number of frames/samples retrieved from the decoder diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c index 5020684a2..e424c0b17 100644 --- a/fftools/ffmpeg_dec.c +++ b/fftools/ffmpeg_dec.c @@ -136,6 +136,8 @@ void dec_free(Decoder **pdec) av_frame_free(&dp->sub_prev[i]); av_frame_free(&dp->sub_heartbeat); + av_freep(&dp->dec.subtitle_header); + av_freep(&dp->parent_name); av_freep(&dp->views_requested); @@ -1621,8 +1623,15 @@ static int dec_open(DecoderPriv *dp, AVDictionary **dec_opts, dp->dec_ctx->extra_hw_frames = extra_frames; } - dp->dec.subtitle_header = dp->dec_ctx->subtitle_header; - dp->dec.subtitle_header_size = dp->dec_ctx->subtitle_header_size; + if (dp->dec_ctx->subtitle_header) { + /* ASS code assumes this buffer is null terminated so add extra byte. */ + dp->dec.subtitle_header = av_mallocz(dp->dec_ctx->subtitle_header_size + 1); + if (!dp->dec.subtitle_header) + return AVERROR(ENOMEM); + memcpy(dp->dec.subtitle_header, dp->dec_ctx->subtitle_header, + dp->dec_ctx->subtitle_header_size); + dp->dec.subtitle_header_size = dp->dec_ctx->subtitle_header_size; + } if (param_out) { if (dp->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) { diff --git a/fftools/graph/graphprint.c b/fftools/graph/graphprint.c index 5b050506d..c2621bc38 100644 --- a/fftools/graph/graphprint.c +++ b/fftools/graph/graphprint.c @@ -33,6 +33,7 @@ #include "libavutil/avassert.h" #include "libavutil/avstring.h" +#include "libavutil/mem.h" #include "libavutil/pixdesc.h" #include "libavutil/dict.h" #include "libavutil/common.h" diff --git a/libavcodec/aac/aacdec.c b/libavcodec/aac/aacdec.c index b8d53036d..679f0324b 100644 --- a/libavcodec/aac/aacdec.c +++ b/libavcodec/aac/aacdec.c @@ -2383,6 +2383,12 @@ static int decode_frame_ga(AVCodecContext *avctx, AACDecContext *ac, ac->oc[1].status = OC_LOCKED; } + if (samples && avctx->sample_rate <= 0) { + av_log(avctx, AV_LOG_ERROR, + "Cannot output a frame without a valid sample rate\n"); + return AVERROR_INVALIDDATA; + } + if (!ac->frame->data[0] && samples) { av_log(avctx, AV_LOG_ERROR, "no frame data found\n"); return AVERROR_INVALIDDATA; diff --git a/libavcodec/aac/aacdec_usac.c b/libavcodec/aac/aacdec_usac.c index 2f4db63ba..4c744e0ee 100644 --- a/libavcodec/aac/aacdec_usac.c +++ b/libavcodec/aac/aacdec_usac.c @@ -215,6 +215,9 @@ static int decode_usac_element_pair(AACDecContext *ac, if (e->stereo_config_index) { e->mps.freq_res = get_bits(gb, 3); /* bsFreqRes */ + if (!e->mps.freq_res) + return AVERROR_INVALIDDATA; /* value 0 is reserved */ + int numBands = ((int[]){0,28,20,14,10,7,5,4})[e->mps.freq_res]; // ISO/IEC 23003-1:2007, 5.2, Table 39 e->mps.fixed_gain = get_bits(gb, 3); /* bsFixedGainDMX */ @@ -374,6 +377,8 @@ int ff_aac_usac_config_decode(AACDecContext *ac, AVCodecContext *avctx, freq_idx = get_bits(gb, 5); /* usacSamplingFrequencyIndex */ if (freq_idx == 0x1f) { samplerate = get_bits(gb, 24); /* usacSamplingFrequency */ + if (samplerate == 0) + return AVERROR(EINVAL); } else { samplerate = ff_aac_usac_samplerate[freq_idx]; if (samplerate < 0) @@ -1385,11 +1390,10 @@ static void decode_tsd(GetBitContext *gb, int *data, break; } int64_t c = k - p + 1; - for (int h = 2; h <= p; h++) { - c *= k - p + h; - c /= h; + for (int h = 2; h <= p && c <= s; h++) { + c += c*(k-p)/h; } - if (s >= (int)c) { /* c is long long for up to 32 slots */ + if (s >= c) { s -= c; data[k] = 1; p--; diff --git a/libavcodec/aac/aacdec_usac_mps212.c b/libavcodec/aac/aacdec_usac_mps212.c index 3c1b1cf30..33c95388f 100644 --- a/libavcodec/aac/aacdec_usac_mps212.c +++ b/libavcodec/aac/aacdec_usac_mps212.c @@ -645,7 +645,7 @@ int ff_aac_ec_data_dec(GetBitContext *gb, AACMPSLosslessData *ld, stride_table[ld->freq_res[set_idx]], start_band, end_band); - if (set_idx + data_pair > MPS_MAX_PARAM_SETS) + if (set_idx + data_pair >= MPS_MAX_PARAM_SETS) return AVERROR(EINVAL); for (int j = 0; j < data_bands; j++) diff --git a/libavcodec/aarch64/vp9lpf_16bpp_neon.S b/libavcodec/aarch64/vp9lpf_16bpp_neon.S index e3e70491c..589775b0f 100644 --- a/libavcodec/aarch64/vp9lpf_16bpp_neon.S +++ b/libavcodec/aarch64/vp9lpf_16bpp_neon.S @@ -56,9 +56,7 @@ mov x11, v4.d[0] mov x12, v4.d[1] adds x11, x11, x12 - b.ne 1f - ret x10 -1: + b.eq 9f .if \wd >= 8 dup v0.8h, w5 @@ -189,13 +187,7 @@ // If no pixels need flat8in, jump to flat8out // (or to a writeout of the inner 4 pixels, for wd=8) .if \wd >= 8 -.if \wd == 16 b.eq 6f -.else - b.ne 1f - ret x13 -1: -.endif // flat8in add \tmp1\().8h, v20.8h, v21.8h @@ -249,20 +241,16 @@ mov x11, v2.d[0] mov x12, v2.d[1] adds x11, x11, x12 - b.ne 1f // If no pixels needed flat8in nor flat8out, jump to a // writeout of the inner 4 pixels - ret x14 -1: + b.eq 7f mov x11, v7.d[0] mov x12, v7.d[1] adds x11, x11, x12 - b.ne 1f // If no pixels need flat8out, jump to a writeout of the inner 6 pixels - ret x15 + b.eq 8f -1: // flat8out // This writes all outputs into v2-v17 (skipping v6 and v16). // If this part is skipped, the output is read from v21-v26 (which is the input @@ -378,35 +366,57 @@ // while we need those for inputs/outputs in wd=16 and use v8-v15 // for temp registers there instead. function vp9_loop_filter_4 + mov x13, #0 loop_filter 4, v16, v17, v18, v19, v28, v29, v30, v31 ret +9: + mov x13, #(1<<9) + ret endfunc function vp9_loop_filter_8 + mov x13, #0 loop_filter 8, v16, v17, v18, v19, v28, v29, v30, v31 ret +6: + mov x13, #(1<<6) + ret +9: + mov x13, #(1<<9) + ret endfunc function vp9_loop_filter_16 + mov x13, #0 loop_filter 16, v8, v9, v10, v11, v12, v13, v14, v15 ret +7: + mov x13, #(1<<7) + ret +8: + mov x13, #(1<<8) + ret +9: + mov x13, #(1<<9) + ret endfunc .macro loop_filter_4 bl vp9_loop_filter_4 + tbnz x13, #9, 9f .endm .macro loop_filter_8 - // calculate alternative 'return' targets - adr x13, 6f bl vp9_loop_filter_8 + tbnz x13, #6, 6f + tbnz x13, #9, 9f .endm .macro loop_filter_16 - // calculate alternative 'return' targets - adr x14, 7f - adr x15, 8f bl vp9_loop_filter_16 + tbnz x13, #7, 7f + tbnz x13, #8, 8f + tbnz x13, #9, 9f .endm @@ -540,7 +550,7 @@ function vp9_loop_filter_v_4_8_16_neon st1 {v23.8h}, [x9], x1 st1 {v25.8h}, [x0], x1 sub x0, x0, x1, lsl #1 - +9: ret x10 endfunc @@ -588,7 +598,7 @@ function vp9_loop_filter_h_4_8_16_neon st1 {v25.d}[1], [x0], x1 sub x0, x0, x1, lsl #3 add x0, x0, #4 - +9: ret x10 endfunc @@ -619,7 +629,7 @@ function vp9_loop_filter_v_8_8_16_neon st1 {v26.8h}, [x0], x1 sub x0, x0, x1, lsl #1 sub x0, x0, x1 - +9: ret x10 6: sub x9, x0, x1, lsl #1 @@ -670,7 +680,7 @@ function vp9_loop_filter_h_8_8_16_neon st1 {v27.8h}, [x0], x1 sub x0, x0, x1, lsl #3 add x0, x0, #8 - +9: ret x10 6: // If we didn't need to do the flat8in part, we use the same writeback @@ -742,7 +752,7 @@ function vp9_loop_filter_v_16_8_16_neon st1 {v17.8h}, [x0], x1 sub x0, x0, x1, lsl #3 add x0, x0, x1 - +9: ret x10 8: add x9, x9, x1, lsl #2 @@ -820,7 +830,7 @@ function vp9_loop_filter_h_16_8_16_neon st1 {v9.8h}, [x9], x1 st1 {v31.8h}, [x0], x1 sub x0, x0, x1, lsl #3 - +9: ret x10 8: // The same writeback as in loop_filter_h_8_8 diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S index 9a79f48df..2ffebcdfc 100644 --- a/libavcodec/aarch64/vp9lpf_neon.S +++ b/libavcodec/aarch64/vp9lpf_neon.S @@ -388,32 +388,28 @@ .endif .if \wd == 16 6: + // If no pixels needed flat8in nor flat8out, jump to a + // writeout of the inner 4 pixels orr v2\sz, v6\sz, v7\sz mov x5, v2.d[0] .ifc \sz, .16b mov x6, v2.d[1] adds x5, x5, x6 - b.ne 1f + b.eq 7f .else - cbnz x5, 1f + cbz x5, 7f .endif - // If no pixels needed flat8in nor flat8out, jump to a - // writeout of the inner 4 pixels - ret x14 -1: + // If no pixels need flat8out, jump to a writeout of the inner 6 pixels mov x5, v7.d[0] .ifc \sz, .16b mov x6, v7.d[1] adds x5, x5, x6 - b.ne 1f + b.eq 8f .else - cbnz x5, 1f + cbz x5, 8f .endif - // If no pixels need flat8out, jump to a writeout of the inner 6 pixels - ret x15 -1: // flat8out // This writes all outputs into v2-v17 (skipping v6 and v16). // If this part is skipped, the output is read from v21-v26 (which is the input @@ -529,76 +525,94 @@ // while we need those for inputs/outputs in wd=16 and use v8-v15 // for temp registers there instead. function vp9_loop_filter_4 + mov x13, #0 loop_filter 4, .8b, 0, v16, v17, v18, v19, v28, v29, v30, v31 ret 9: - ret x10 + mov x13, #(1<<9) + ret endfunc function vp9_loop_filter_4_16b_mix_44 + mov x13, #0 loop_filter 4, .16b, 44, v16, v17, v18, v19, v28, v29, v30, v31 ret 9: - ret x10 + mov x13, #(1<<9) + ret endfunc function vp9_loop_filter_8 + mov x13, #0 loop_filter 8, .8b, 0, v16, v17, v18, v19, v28, v29, v30, v31 ret 6: - ret x13 + mov x13, #(1<<6) + ret 9: - ret x10 + mov x13, #(1<<9) + ret endfunc function vp9_loop_filter_8_16b_mix + mov x13, #0 loop_filter 8, .16b, 88, v16, v17, v18, v19, v28, v29, v30, v31 ret 6: - ret x13 + mov x13, #(1<<6) + ret 9: - ret x10 + mov x13, #(1<<9) + ret endfunc function vp9_loop_filter_16 + mov x13, #0 loop_filter 16, .8b, 0, v8, v9, v10, v11, v12, v13, v14, v15 ret +7: + mov x13, #(1<<7) + ret +8: + mov x13, #(1<<8) + ret 9: - ldp d10, d11, [sp, #0x10] - ldp d12, d13, [sp, #0x20] - ldp d14, d15, [sp, #0x30] - ldp d8, d9, [sp], #0x40 - ret x10 + mov x13, #(1<<9) + ret endfunc function vp9_loop_filter_16_16b + mov x13, #0 loop_filter 16, .16b, 0, v8, v9, v10, v11, v12, v13, v14, v15 ret +7: + mov x13, #(1<<7) + ret +8: + mov x13, #(1<<8) + ret 9: - ldp d10, d11, [sp, #0x10] - ldp d12, d13, [sp, #0x20] - ldp d14, d15, [sp, #0x30] - ldp d8, d9, [sp], #0x40 - ret x10 + mov x13, #(1<<9) + ret endfunc .macro loop_filter_4 bl vp9_loop_filter_4 + tbnz x13, #9, 9f .endm .macro loop_filter_4_16b_mix mix bl vp9_loop_filter_4_16b_mix_\mix + tbnz x13, #9, 9f .endm .macro loop_filter_8 - // calculate alternative 'return' targets - adr x13, 6f bl vp9_loop_filter_8 + tbnz x13, #6, 6f + tbnz x13, #9, 9f .endm .macro loop_filter_8_16b_mix mix - // calculate alternative 'return' targets - adr x13, 6f .if \mix == 48 mov x11, #0xffffffff00000000 .elseif \mix == 84 @@ -607,20 +621,22 @@ endfunc mov x11, #0xffffffffffffffff .endif bl vp9_loop_filter_8_16b_mix + tbnz x13, #6, 6f + tbnz x13, #9, 9f .endm .macro loop_filter_16 - // calculate alternative 'return' targets - adr x14, 7f - adr x15, 8f bl vp9_loop_filter_16 + tbnz x13, #7, 7f + tbnz x13, #8, 8f + tbnz x13, #9, 9f .endm .macro loop_filter_16_16b - // calculate alternative 'return' targets - adr x14, 7f - adr x15, 8f bl vp9_loop_filter_16_16b + tbnz x13, #7, 7f + tbnz x13, #8, 8f + tbnz x13, #9, 9f .endm @@ -647,7 +663,7 @@ function ff_vp9_loop_filter_v_4_8_neon, export=1 st1 {v24.8b}, [x0], x1 st1 {v23.8b}, [x9], x1 st1 {v25.8b}, [x0], x1 - +9: ret x10 endfunc @@ -671,7 +687,7 @@ function ff_vp9_loop_filter_v_44_16_neon, export=1 st1 {v24.16b}, [x0], x1 st1 {v23.16b}, [x9], x1 st1 {v25.16b}, [x0], x1 - +9: ret x10 endfunc @@ -713,7 +729,7 @@ function ff_vp9_loop_filter_h_4_8_neon, export=1 st1 {v24.s}[1], [x0], x1 st1 {v25.s}[0], [x9], x1 st1 {v25.s}[1], [x0], x1 - +9: ret x10 endfunc @@ -765,7 +781,7 @@ function ff_vp9_loop_filter_h_44_16_neon, export=1 st1 {v24.s}[3], [x0], x1 st1 {v25.s}[1], [x9], x1 st1 {v25.s}[3], [x0], x1 - +9: ret x10 endfunc @@ -792,7 +808,7 @@ function ff_vp9_loop_filter_v_8_8_neon, export=1 st1 {v25.8b}, [x0], x1 st1 {v23.8b}, [x9], x1 st1 {v26.8b}, [x0], x1 - +9: ret x10 6: sub x9, x0, x1, lsl #1 @@ -827,7 +843,7 @@ function ff_vp9_loop_filter_v_\mix\()_16_neon, export=1 st1 {v25.16b}, [x0], x1 st1 {v23.16b}, [x9], x1 st1 {v26.16b}, [x0], x1 - +9: ret x10 6: sub x9, x0, x1, lsl #1 @@ -875,7 +891,7 @@ function ff_vp9_loop_filter_h_8_8_neon, export=1 st1 {v26.8b}, [x0], x1 st1 {v23.8b}, [x9], x1 st1 {v27.8b}, [x0], x1 - +9: ret x10 6: // If we didn't need to do the flat8in part, we use the same writeback @@ -941,7 +957,7 @@ function ff_vp9_loop_filter_h_\mix\()_16_neon, export=1 st1 {v26.d}[1], [x0], x1 st1 {v27.8b}, [x9], x1 st1 {v27.d}[1], [x0], x1 - +9: ret x10 6: add x9, x9, #2 diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index e06aa7606..74af2cb4d 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -294,7 +294,8 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) break; case AV_CODEC_ID_ADPCM_PSXC: max_channels = 8; - if (avctx->ch_layout.nb_channels <= 0 || avctx->block_align <= 0) + if (avctx->ch_layout.nb_channels <= 0 || avctx->block_align <= 0 || + avctx->block_align % avctx->ch_layout.nb_channels) return AVERROR_INVALIDDATA; break; case AV_CODEC_ID_ADPCM_IMA_DAT4: @@ -1173,7 +1174,7 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, if(ch <= 0) return 0; - if (buf_size > INT_MAX / 2) + if (buf_size > INT_MAX / 14) return 0; switch (avctx->codec->id) { diff --git a/libavcodec/agm.c b/libavcodec/agm.c index c13b4d963..5d27d1727 100644 --- a/libavcodec/agm.c +++ b/libavcodec/agm.c @@ -409,12 +409,14 @@ static int decode_inter_plane(AGMContext *s, GetBitContext *gb, int size, int map = s->map[x]; if (orig_mv_x >= -32) { - if (y * 8 + mv_y < 0 || y * 8 + mv_y + 8 > h || - x * 8 + mv_x < 0 || x * 8 + mv_x + 8 > w) + int src_y = (s->blocks_h - 1 - y) * 8 - mv_y; + int src_x = x * 8 + mv_x; + if (src_y < 0 || src_y + 8 > h || + src_x < 0 || src_x + 8 > w) return AVERROR_INVALIDDATA; copy_block8(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, - prev->data[plane] + ((s->blocks_h - 1 - y) * 8 - mv_y) * prev->linesize[plane] + (x * 8 + mv_x), + prev->data[plane] + src_y * prev->linesize[plane] + src_x, frame->linesize[plane], prev->linesize[plane], 8); if (map) { s->idsp.idct(s->wblocks + x * 64); @@ -446,12 +448,14 @@ static int decode_inter_plane(AGMContext *s, GetBitContext *gb, int size, return ret; if (orig_mv_x >= -32) { - if (y * 8 + mv_y < 0 || y * 8 + mv_y + 8 > h || - x * 8 + mv_x < 0 || x * 8 + mv_x + 8 > w) + int src_y = (s->blocks_h - 1 - y) * 8 - mv_y; + int src_x = x * 8 + mv_x; + if (src_y < 0 || src_y + 8 > h || + src_x < 0 || src_x + 8 > w) return AVERROR_INVALIDDATA; copy_block8(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, - prev->data[plane] + ((s->blocks_h - 1 - y) * 8 - mv_y) * prev->linesize[plane] + (x * 8 + mv_x), + prev->data[plane] + src_y * prev->linesize[plane] + src_x, frame->linesize[plane], prev->linesize[plane], 8); if (map) { s->idsp.idct(s->block); diff --git a/libavcodec/apv_decode.c b/libavcodec/apv_decode.c index dbe354a79..b6a3d3305 100644 --- a/libavcodec/apv_decode.c +++ b/libavcodec/apv_decode.c @@ -208,14 +208,13 @@ static int apv_decode_tile_component(AVCodecContext *avctx, void *data, { APVRawFrame *input = data; APVDecodeContext *apv = avctx->priv_data; - const CodedBitstreamAPVContext *apv_cbc = apv->cbc->priv_data; const APVDerivedTileInfo *tile_info = &apv->tile_info; - - int tile_index = job / apv_cbc->num_comp; - int comp_index = job % apv_cbc->num_comp; - const AVPixFmtDescriptor *pix_fmt_desc = av_pix_fmt_desc_get(avctx->pix_fmt); + int nb_components = pix_fmt_desc->nb_components; + + int tile_index = job / nb_components; + int comp_index = job % nb_components; int sub_w_shift = comp_index == 0 ? 0 : pix_fmt_desc->log2_chroma_w; int sub_h_shift = comp_index == 0 ? 0 : pix_fmt_desc->log2_chroma_h; @@ -266,7 +265,7 @@ static int apv_decode_tile_component(AVCodecContext *avctx, void *data, int qp = tile->tile_header.tile_qp[comp_index]; int level_scale = apv_level_scale[qp % 6]; - bit_depth = apv_cbc->bit_depth; + bit_depth = input->frame_header.frame_info.bit_depth_minus8 + 8; qp_shift = qp / 6; for (int y = 0; y < 8; y++) { diff --git a/libavcodec/bsf/dts2pts.c b/libavcodec/bsf/dts2pts.c index 122661a5d..24d112e13 100644 --- a/libavcodec/bsf/dts2pts.c +++ b/libavcodec/bsf/dts2pts.c @@ -412,11 +412,23 @@ static int hevc_init_nb_frame(AVBSFContext *ctx, int poc) return 0; } -static int same_gop(void *opaque, void *elem) +typedef struct DTS2PTSCollect { + int gop; + DTS2PTSNode **out; + int count; + int max; +} DTS2PTSCollect; + +static int collect_same_gop(void *opaque, void *elem) { + DTS2PTSCollect *c = opaque; DTS2PTSNode *node = elem; - int gop = ((int *)opaque)[1]; - return FFDIFFSIGN(gop, node->gop); + if (node->gop == c->gop) { + if (c->count < c->max) + c->out[c->count] = node; + c->count++; + } + return 0; } static int hevc_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, bool *queued) @@ -440,10 +452,26 @@ static int hevc_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, bool *que } if (poc < s->nb_frame && hevc->gop == s->gop) { - int tmp[] = {s->nb_frame - poc, s->gop}; + int dec = s->nb_frame - poc; + DTS2PTSNode *nodes[HEVC_MAX_DPB_SIZE * 2]; + DTS2PTSCollect c = { s->gop, nodes, 0, FF_ARRAY_ELEMS(nodes) }; - s->nb_frame -= tmp[0]; - av_tree_enumerate(s->root, tmp, same_gop, dec_poc); + s->nb_frame -= dec; + + av_tree_enumerate(s->root, &c, NULL, collect_same_gop); + av_assert0(c.count <= c.max); + for (int i = 0; i < c.count; i++) { + struct AVTreeNode *tnode = NULL; + DTS2PTSNode *r; + av_tree_insert(&s->root, nodes[i], cmp_insert, &tnode); + nodes[i]->poc -= dec; + r = av_tree_insert(&s->root, nodes[i], cmp_insert, &tnode); + if (r && r != nodes[i]) { + *r = *nodes[i]; + av_refstruct_unref(&nodes[i]); + av_free(tnode); + } + } } ret = alloc_and_insert_node(ctx, pkt->dts, pkt->duration, s->nb_frame, 1, s->gop); diff --git a/libavcodec/bsf/smpte436m_to_eia608.c b/libavcodec/bsf/smpte436m_to_eia608.c index 529ae8879..268108c9a 100644 --- a/libavcodec/bsf/smpte436m_to_eia608.c +++ b/libavcodec/bsf/smpte436m_to_eia608.c @@ -73,7 +73,7 @@ static int ff_smpte436m_to_eia608_filter(AVBSFContext *ctx, AVPacket *out) return 0; } if (ret != AVERROR_EOF) - return ret; + goto fail; ret = AVERROR(EAGAIN); fail: diff --git a/libavcodec/cbs_av1_syntax_template.c b/libavcodec/cbs_av1_syntax_template.c index 86b9a3161..74ab46041 100644 --- a/libavcodec/cbs_av1_syntax_template.c +++ b/libavcodec/cbs_av1_syntax_template.c @@ -186,10 +186,13 @@ static int FUNC(decoder_model_info)(CodedBitstreamContext *ctx, RWContext *rw, static int FUNC(sequence_header_obu)(CodedBitstreamContext *ctx, RWContext *rw, AV1RawSequenceHeader *current) { + CodedBitstreamAV1Context *priv = ctx->priv_data; int i, err; HEADER("Sequence Header"); + priv->seen_frame_header = 0; + fc(3, seq_profile, AV_PROFILE_AV1_MAIN, AV_PROFILE_AV1_PROFESSIONAL); flag(still_picture); diff --git a/libavcodec/cbs_h266_syntax_template.c b/libavcodec/cbs_h266_syntax_template.c index 98a895494..17d31d5b4 100644 --- a/libavcodec/cbs_h266_syntax_template.c +++ b/libavcodec/cbs_h266_syntax_template.c @@ -1133,7 +1133,7 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw, max_width_minus1 = tmp_width_val - 1; max_height_minus1 = tmp_height_val - 1; - flag(sps_subpic_info_present_flag); + u(1, sps_subpic_info_present_flag, 0, !current->sps_res_change_in_clvs_allowed_flag); if (current->sps_subpic_info_present_flag) { ue(sps_num_subpics_minus1, 0, VVC_MAX_SLICES - 1); if (current->sps_num_subpics_minus1 > 0) { @@ -2022,7 +2022,7 @@ static int FUNC(pps) (CodedBitstreamContext *ctx, RWContext *rw, for (j = 0; j < current->pps_num_exp_slices_in_tile[i]; j++) { ues(pps_exp_slice_height_in_ctus_minus1[i][j], 0, - remaining_height_in_ctbs_y - 1, 2, + remaining_height_in_ctbs_y - (current->pps_num_exp_slices_in_tile[i] - j), 2, i, j); slice_height_in_ctus = current-> @@ -3145,7 +3145,7 @@ static int FUNC(slice_header) (CodedBitstreamContext *ctx, RWContext *rw, if (!pps->pps_rect_slice_flag && pps->num_tiles_in_pic - current->sh_slice_address > 1) - ue(sh_num_tiles_in_slice_minus1, 0, pps->num_tiles_in_pic - 1); + ue(sh_num_tiles_in_slice_minus1, 0, pps->num_tiles_in_pic - 1 - current->sh_slice_address); else infer(sh_num_tiles_in_slice_minus1, 0); diff --git a/libavcodec/cook.c b/libavcodec/cook.c index cc6005d3f..8256afc2e 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -1080,6 +1080,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) int s = 0; unsigned int channel_mask = 0; int samples_per_frame = 0; + int total_channels = 0; int ret; int channels = avctx->ch_layout.nb_channels; @@ -1237,10 +1238,12 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) q->subpacket[s].gains2.now = q->subpacket[s].gain_3; q->subpacket[s].gains2.previous = q->subpacket[s].gain_4; - if (q->num_subpackets + q->subpacket[s].num_channels > channels) { - av_log(avctx, AV_LOG_ERROR, "Too many subpackets %d for channels %d\n", q->num_subpackets, channels); + if (total_channels + q->subpacket[s].num_channels > channels) { + av_log(avctx, AV_LOG_ERROR, "Too many subpacket channels %d for channels %d\n", + total_channels + q->subpacket[s].num_channels, channels); return AVERROR_INVALIDDATA; } + total_channels += q->subpacket[s].num_channels; q->num_subpackets++; s++; diff --git a/libavcodec/cri.c b/libavcodec/cri.c index f38059723..72f1eff9d 100644 --- a/libavcodec/cri.c +++ b/libavcodec/cri.c @@ -69,6 +69,7 @@ static av_cold int cri_decode_init(AVCodecContext *avctx) s->jpeg_avctx->flags = avctx->flags; s->jpeg_avctx->flags2 = avctx->flags2; s->jpeg_avctx->idct_algo = avctx->idct_algo; + s->jpeg_avctx->max_pixels = avctx->max_pixels; ret = avcodec_open2(s->jpeg_avctx, NULL, NULL); if (ret < 0) return ret; diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index 2eabf7427..a4a719aa8 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -339,9 +339,9 @@ static int alloc_buffers(DiracContext *s, int stride) av_freep(&s->mctmp); av_freep(&s->mcscratch); - s->edge_emu_buffer_base = av_malloc_array(stride, MAX_BLOCKSIZE); + s->edge_emu_buffer_base = av_malloc_array(stride, 4 * MAX_BLOCKSIZE); - s->mctmp = av_malloc_array((stride+MAX_BLOCKSIZE), (h+MAX_BLOCKSIZE) * sizeof(*s->mctmp)); + s->mctmp = av_malloc_array((stride+MAX_BLOCKSIZE), (h + 5*MAX_BLOCKSIZE) * sizeof(*s->mctmp)); s->mcscratch = av_malloc_array(stride, MAX_BLOCKSIZE); if (!s->edge_emu_buffer_base || !s->mctmp || !s->mcscratch) @@ -1895,7 +1895,7 @@ static int dirac_decode_frame_internal(DiracContext *s) /* FIXME: small resolutions */ for (i = 0; i < 4; i++) - s->edge_emu_buffer[i] = s->edge_emu_buffer_base + i*FFALIGN(p->width, 16); + s->edge_emu_buffer[i] = s->edge_emu_buffer_base + i*s->buffer_stride*MAX_BLOCKSIZE; if (!s->zero_res && !s->low_delay) { @@ -1944,7 +1944,7 @@ static int dirac_decode_frame_internal(DiracContext *s) h = p->height - start; else h = p->ybsep - (start - dsty); - if (h < 0) + if (h <= 0) break; memset(mctmp+2*p->yoffset*p->stride, 0, 2*rowheight); diff --git a/libavcodec/fastaudio.c b/libavcodec/fastaudio.c index d361b410b..bab3cb738 100644 --- a/libavcodec/fastaudio.c +++ b/libavcodec/fastaudio.c @@ -113,6 +113,8 @@ static int fastaudio_decode(AVCodecContext *avctx, AVFrame *frame, int ret; subframes = pkt->size / (40 * avctx->ch_layout.nb_channels); + if (subframes <= 0 || subframes > INT_MAX / 256) + return AVERROR_INVALIDDATA; frame->nb_samples = subframes * 256; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c index a4900641e..f3347e951 100644 --- a/libavcodec/g2meet.c +++ b/libavcodec/g2meet.c @@ -481,12 +481,13 @@ static void epic_free_pixel_cache(ePICPixHash *hash) static inline int is_pixel_on_stack(const ePICContext *dc, uint32_t pix) { int i; + int n = FFMIN(dc->stack_pos, EPIC_PIX_STACK_SIZE); - for (i = 0; i < dc->stack_pos; i++) + for (i = 0; i < n; i++) if (dc->stack[i] == pix) break; - return i != dc->stack_pos; + return i != n; } #define TOSIGNED(val) (((val) >> 1) ^ -((val) & 1)) diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c index 638362fbf..c9fb25b1d 100644 --- a/libavcodec/h2645_sei.c +++ b/libavcodec/h2645_sei.c @@ -629,15 +629,15 @@ static int h2645_sei_to_side_data(AVCodecContext *avctx, H2645SEI *sei, return AVERROR(ENOMEM); } + dst_env->ambient_illuminance = av_make_q(env->ambient_illuminance, 10000); + dst_env->ambient_light_x = av_make_q(env->ambient_light_x, 50000); + dst_env->ambient_light_y = av_make_q(env->ambient_light_y, 50000); + ret = ff_frame_new_side_data_from_buf_ext(avctx, sd, nb_sd, AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT, &buf); if (ret < 0) return ret; - - dst_env->ambient_illuminance = av_make_q(env->ambient_illuminance, 10000); - dst_env->ambient_light_x = av_make_q(env->ambient_light_x, 50000); - dst_env->ambient_light_y = av_make_q(env->ambient_light_y, 50000); } if (sei->mastering_display.present) { diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index dbf7f6023..e3b4436fc 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -316,8 +316,10 @@ static void color_frame(AVFrame *frame, const int c[4]) int bytes = is_chroma ? AV_CEIL_RSHIFT(frame->width, desc->log2_chroma_w) : frame->width; int height = is_chroma ? AV_CEIL_RSHIFT(frame->height, desc->log2_chroma_h) : frame->height; if (desc->comp[0].depth >= 9) { - ((uint16_t*)dst)[0] = c[p]; - av_memcpy_backptr(dst + 2, 2, bytes - 2); + if (bytes >= 1) + ((uint16_t*)dst)[0] = c[p]; + if (bytes >= 2) + av_memcpy_backptr(dst + 2, 2, 2 * (bytes - 1)); dst += frame->linesize[p]; for (int y = 1; y < height; y++) { memcpy(dst, frame->data[p], 2*bytes); diff --git a/libavcodec/hdrdec.c b/libavcodec/hdrdec.c index cffa7570d..1a6935ff7 100644 --- a/libavcodec/hdrdec.c +++ b/libavcodec/hdrdec.c @@ -72,7 +72,7 @@ static int decompress(uint8_t *scanline, int w, GetByteContext *gb, const uint8_ for (int i = run << rshift; i > 0 && w > 0 && scanline >= start + 4; i--) { memcpy(scanline, scanline - 4, 4); scanline += 4; - w -= 4; + w--; } rshift += 8; if (rshift > 16) diff --git a/libavcodec/hevc/ps.c b/libavcodec/hevc/ps.c index c67aab151..a21563c2e 100644 --- a/libavcodec/hevc/ps.c +++ b/libavcodec/hevc/ps.c @@ -62,6 +62,29 @@ static const uint8_t hevc_sub_height_c[] = { 1, 2, 1, 1 }; +static int read_window(HEVCWindow *window, GetBitContext *gb, int chroma_format_idc, int w, int h) +{ + int64_t vert_mult = hevc_sub_height_c[chroma_format_idc]; + int64_t horiz_mult = hevc_sub_width_c [chroma_format_idc]; + int64_t left = get_ue_golomb_long(gb) * horiz_mult; + int64_t right = get_ue_golomb_long(gb) * horiz_mult; + int64_t top = get_ue_golomb_long(gb) * vert_mult; + int64_t bottom = get_ue_golomb_long(gb) * vert_mult; + + if (left < 0 || right < 0 || top < 0 || bottom < 0 || + w <= left + right || + h <= top + bottom) { + memset(window, 0, sizeof(*window)); + return AVERROR_INVALIDDATA; + } + + window->left_offset = left; + window->right_offset = right; + window->top_offset = top; + window->bottom_offset = bottom; + return 0; +} + static void remove_sps(HEVCParamSets *s, int id) { int i; @@ -702,12 +725,9 @@ static int decode_vps_ext(GetBitContext *gb, AVCodecContext *avctx, HEVCVPS *vps } if (get_bits1(gb) /* conformance_window_vps_flag */) { - int vert_mult = hevc_sub_height_c[vps->rep_format.chroma_format_idc]; - int horiz_mult = hevc_sub_width_c[vps->rep_format.chroma_format_idc]; - vps->rep_format.conf_win_left_offset = get_ue_golomb(gb) * horiz_mult; - vps->rep_format.conf_win_right_offset = get_ue_golomb(gb) * horiz_mult; - vps->rep_format.conf_win_top_offset = get_ue_golomb(gb) * vert_mult; - vps->rep_format.conf_win_bottom_offset = get_ue_golomb(gb) * vert_mult; + int ret = read_window(&vps->rep_format.conf_win, gb, vps->rep_format.chroma_format_idc, vps->rep_format.pic_width_in_luma_samples, vps->rep_format.pic_height_in_luma_samples); + if (ret < 0) + return ret; } vps->max_one_active_ref_layer = get_bits1(gb); @@ -962,12 +982,7 @@ static void decode_vui(GetBitContext *gb, AVCodecContext *avctx, vui->default_display_window_flag = get_bits1(gb); if (vui->default_display_window_flag) { - int vert_mult = hevc_sub_height_c[sps->chroma_format_idc]; - int horiz_mult = hevc_sub_width_c[sps->chroma_format_idc]; - vui->def_disp_win.left_offset = get_ue_golomb_long(gb) * horiz_mult; - vui->def_disp_win.right_offset = get_ue_golomb_long(gb) * horiz_mult; - vui->def_disp_win.top_offset = get_ue_golomb_long(gb) * vert_mult; - vui->def_disp_win.bottom_offset = get_ue_golomb_long(gb) * vert_mult; + read_window(&vui->def_disp_win, gb, sps->chroma_format_idc, sps->width, sps->height); if (apply_defdispwin && avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) { @@ -1284,10 +1299,10 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, sps->height, 0, avctx)) < 0) return ret; - sps->pic_conf_win.left_offset = rf->conf_win_left_offset; - sps->pic_conf_win.right_offset = rf->conf_win_right_offset; - sps->pic_conf_win.top_offset = rf->conf_win_top_offset; - sps->pic_conf_win.bottom_offset = rf->conf_win_bottom_offset; + sps->pic_conf_win.left_offset = rf->conf_win.left_offset; + sps->pic_conf_win.right_offset = rf->conf_win.right_offset; + sps->pic_conf_win.top_offset = rf->conf_win.top_offset; + sps->pic_conf_win.bottom_offset = rf->conf_win.bottom_offset; } else { sps->chroma_format_idc = get_ue_golomb_long(gb); @@ -1310,12 +1325,9 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, sps->conformance_window = get_bits1(gb); if (sps->conformance_window) { - int vert_mult = hevc_sub_height_c[sps->chroma_format_idc]; - int horiz_mult = hevc_sub_width_c[sps->chroma_format_idc]; - sps->pic_conf_win.left_offset = get_ue_golomb_long(gb) * horiz_mult; - sps->pic_conf_win.right_offset = get_ue_golomb_long(gb) * horiz_mult; - sps->pic_conf_win.top_offset = get_ue_golomb_long(gb) * vert_mult; - sps->pic_conf_win.bottom_offset = get_ue_golomb_long(gb) * vert_mult; + ret = read_window(&sps->pic_conf_win, gb, sps->chroma_format_idc, sps->width, sps->height); + if (ret < 0) + return ret; if (avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) { av_log(avctx, AV_LOG_DEBUG, diff --git a/libavcodec/hevc/ps.h b/libavcodec/hevc/ps.h index d620887b8..f5c5f81a6 100644 --- a/libavcodec/hevc/ps.h +++ b/libavcodec/hevc/ps.h @@ -162,10 +162,7 @@ typedef struct RepFormat { uint8_t separate_colour_plane_flag; uint8_t bit_depth_luma; ///< bit_depth_vps_luma_minus8 + 8 uint8_t bit_depth_chroma; ///< bit_depth_vps_chroma_minus8 + 8 - uint16_t conf_win_left_offset; - uint16_t conf_win_right_offset; - uint16_t conf_win_top_offset; - uint16_t conf_win_bottom_offset; + HEVCWindow conf_win; } RepFormat; typedef struct HEVCVPS { diff --git a/libavcodec/hevc/refs.c b/libavcodec/hevc/refs.c index 1faede4e3..f53768f81 100644 --- a/libavcodec/hevc/refs.c +++ b/libavcodec/hevc/refs.c @@ -473,12 +473,13 @@ static HEVCFrame *generate_missing_ref(HEVCContext *s, HEVCLayerContext *l, int return NULL; if (!s->avctx->hwaccel) { + int nb_planes = l->sps->chroma_format_idc ? 3 : 1; if (!l->sps->pixel_shift) { - for (i = 0; frame->f->data[i]; i++) + for (i = 0; i < nb_planes; i++) memset(frame->f->data[i], 1 << (l->sps->bit_depth - 1), frame->f->linesize[i] * AV_CEIL_RSHIFT(l->sps->height, l->sps->vshift[i])); } else { - for (i = 0; frame->f->data[i]; i++) + for (i = 0; i < nb_planes; i++) for (y = 0; y < (l->sps->height >> l->sps->vshift[i]); y++) { uint8_t *dst = frame->f->data[i] + y * frame->f->linesize[i]; AV_WN16(dst, 1 << (l->sps->bit_depth - 1)); diff --git a/libavcodec/imm5.c b/libavcodec/imm5.c index b1cda453c..d130db76a 100644 --- a/libavcodec/imm5.c +++ b/libavcodec/imm5.c @@ -62,6 +62,7 @@ static av_cold int imm5_init(AVCodecContext *avctx) ctx->h264_avctx->thread_count = 1; ctx->h264_avctx->flags = avctx->flags; ctx->h264_avctx->flags2 = avctx->flags2; + ctx->h264_avctx->max_pixels = avctx->max_pixels; ret = avcodec_open2(ctx->h264_avctx, NULL, NULL); if (ret < 0) return ret; @@ -73,6 +74,7 @@ static av_cold int imm5_init(AVCodecContext *avctx) ctx->hevc_avctx->thread_count = 1; ctx->hevc_avctx->flags = avctx->flags; ctx->hevc_avctx->flags2 = avctx->flags2; + ctx->hevc_avctx->max_pixels = avctx->max_pixels; ret = avcodec_open2(ctx->hevc_avctx, NULL, NULL); if (ret < 0) return ret; diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 61ea7e7fa..8b6b7cc1e 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -1957,7 +1957,7 @@ static void decode_clnpass(const Jpeg2000DecoderContext *s, Jpeg2000T1Context *t int width, int height, int bpno, int bandno, int seg_symbols, int vert_causal_ctx_csty_symbol) { - int mask = 3 << (bpno - 1), y0, x, y, runlen, dec; + int mask = (3u << bpno)>>1, y0, x, y, runlen, dec; for (y0 = 0; y0 < height; y0 += 4) { for (x = 0; x < width; x++) { @@ -2448,8 +2448,14 @@ static void jpeg2000_dec_cleanup(Jpeg2000DecoderContext *s) memset(s->qntsty, 0, sizeof(s->qntsty)); memset(s->properties, 0, sizeof(s->properties)); memset(&s->poc , 0, sizeof(s->poc)); + memset(s->roi_shift, 0, sizeof(s->roi_shift)); s->numXtiles = s->numYtiles = 0; s->ncomponents = 0; + s->has_ppm = 0; + s->isHT = 0; + s->precision = 0; + s->colour_space = 0; + s->pal8 = 0; } static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s) diff --git a/libavcodec/jpeg2000htdec.c b/libavcodec/jpeg2000htdec.c index 9fc269306..5b12062f4 100644 --- a/libavcodec/jpeg2000htdec.c +++ b/libavcodec/jpeg2000htdec.c @@ -1334,8 +1334,19 @@ ff_jpeg2000_decode_htj2k(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c sign = val & INT32_MIN; val &= INT32_MAX; /* ROI shift, if necessary */ - if (roi_shift && (((uint32_t)val & ~mask) == 0)) - val <<= roi_shift; + if (roi_shift && (((uint32_t)val & ~mask) == 0)) { + if ((32 - ff_clz(val | 1)) < roi_shift) + // Assuming that the internal precision for codeblock decoding is 32 bits. + val <<= roi_shift; + else { + av_log(s->avctx, AV_LOG_ERROR, + "Pixel precision in ROI is beyond the supported range.\n" + ); + ret = AVERROR_PATCHWELCOME; + goto free; + } + + } t1->data[n] = val | sign; /* NOTE: Binary point for reconstruction value is located in 31 - M_b */ } } diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c index 4b07f1f8d..5c2f0f420 100644 --- a/libavcodec/jpeglsdec.c +++ b/libavcodec/jpeglsdec.c @@ -499,7 +499,7 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s) if (s->bits <= 8) { uint8_t *src = s->picture_ptr->data[0]; - for (i = 0; i < s->height; i++) { + for (i = 0; i < decoded_height; i++) { switch(s->xfrm) { case 1: for (x = off; x + 2 < w; x += 3) { diff --git a/libavcodec/libjxlenc.c b/libavcodec/libjxlenc.c index ca4606154..228a8eb6a 100644 --- a/libavcodec/libjxlenc.c +++ b/libavcodec/libjxlenc.c @@ -434,7 +434,8 @@ static int libjxl_preprocess_stream(AVCodecContext *avctx, const AVFrame *frame, if (ret >= 0) ret = av_exif_get_entry(avctx, &ifd, tag, 0, &orient); if (ret >= 0 && orient) { - if (!have_matrix && orient->value.uint[0] >= 1 && orient->value.uint[0] <= 8) { + if (!have_matrix && orient->type == AV_TIFF_SHORT && orient->count + && orient->value.uint[0] >= 1 && orient->value.uint[0] <= 8) { av_exif_orientation_to_matrix(matrix, orient->value.uint[0]); have_matrix = 1; } diff --git a/libavcodec/liboapvenc.c b/libavcodec/liboapvenc.c index 84bd175ef..2b4da37b7 100644 --- a/libavcodec/liboapvenc.c +++ b/libavcodec/liboapvenc.c @@ -59,8 +59,6 @@ typedef struct ApvEncContext { oapv_frms_t ifrms; // frames for input - int num_frames; // number of frames in an access unit - int preset_id; // preset of apv ( fastest, fast, medium, slow, placebo) int qp; // quantization parameter (QP) [0,63] @@ -129,6 +127,121 @@ static inline int get_color_format(enum AVPixelFormat pix_fmt) return cf; } +static inline int get_chroma_format_idc(enum AVPixelFormat pix_fmt) +{ + int cfi = -1; + + switch (pix_fmt) { + case AV_PIX_FMT_GRAY10: + cfi = APV_CHROMA_FORMAT_400; + break; + case AV_PIX_FMT_YUV422P10: + case AV_PIX_FMT_YUV422P12: + cfi = APV_CHROMA_FORMAT_422; + break; + case AV_PIX_FMT_YUV444P10: + case AV_PIX_FMT_YUV444P12: + cfi = APV_CHROMA_FORMAT_444; + break; + case AV_PIX_FMT_YUVA444P10: + case AV_PIX_FMT_YUVA444P12: + cfi = APV_CHROMA_FORMAT_4444; + break; + default: + av_assert0(cfi >= 0); + } + + return cfi; +} + +static inline int get_min_profile(enum AVPixelFormat pix_fmt) +{ + int profile = AV_PROFILE_UNKNOWN; + + switch (pix_fmt) { + case AV_PIX_FMT_GRAY10: + profile = AV_PROFILE_APV_400_10; + break; + case AV_PIX_FMT_YUV422P10: + profile = AV_PROFILE_APV_422_10; + break; + case AV_PIX_FMT_YUV422P12: + profile = AV_PROFILE_APV_422_12; + break; + case AV_PIX_FMT_YUV444P10: + profile = AV_PROFILE_APV_444_10; + break; + case AV_PIX_FMT_YUV444P12: + profile = AV_PROFILE_APV_444_12; + break; + case AV_PIX_FMT_YUVA444P10: + profile = AV_PROFILE_APV_4444_10; + break; + case AV_PIX_FMT_YUVA444P12: + profile = AV_PROFILE_APV_4444_12; + break; + default: + av_assert0(profile != AV_PROFILE_UNKNOWN); + } + + return profile; +} + +static int profile_is_compatible(enum AVPixelFormat pix_fmt, int profile) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + const int chroma_format_idc = get_chroma_format_idc(pix_fmt); + const int bit_depth = desc->comp[0].depth; + + av_assert0(desc); + + switch (profile) { + case AV_PROFILE_APV_422_10: + return chroma_format_idc == APV_CHROMA_FORMAT_422 && bit_depth == 10; + case AV_PROFILE_APV_422_12: + return chroma_format_idc == APV_CHROMA_FORMAT_422 && + bit_depth >= 10 && bit_depth <= 12; + case AV_PROFILE_APV_444_10: + return chroma_format_idc >= APV_CHROMA_FORMAT_422 && + chroma_format_idc <= APV_CHROMA_FORMAT_444 && + bit_depth == 10; + case AV_PROFILE_APV_444_12: + return chroma_format_idc >= APV_CHROMA_FORMAT_422 && + chroma_format_idc <= APV_CHROMA_FORMAT_444 && + bit_depth >= 10 && bit_depth <= 12; + case AV_PROFILE_APV_4444_10: + return chroma_format_idc >= APV_CHROMA_FORMAT_422 && + chroma_format_idc <= APV_CHROMA_FORMAT_4444 && + bit_depth == 10; + case AV_PROFILE_APV_4444_12: + return chroma_format_idc >= APV_CHROMA_FORMAT_422 && + chroma_format_idc <= APV_CHROMA_FORMAT_4444 && + bit_depth >= 10 && bit_depth <= 12; + case AV_PROFILE_APV_400_10: + return chroma_format_idc == APV_CHROMA_FORMAT_400 && bit_depth == 10; + default: + return 0; + } +} + +static int validate_profile(AVCodecContext *avctx, int profile) +{ + const int minimum = get_min_profile(avctx->pix_fmt); + const char *profile_name = av_get_profile_name(avctx->codec, profile); + const char *minimum_name = av_get_profile_name(avctx->codec, minimum); + + if (!profile_is_compatible(avctx->pix_fmt, profile)) { + av_log(avctx, AV_LOG_ERROR, + "Profile %s (%d) is incompatible with pixel format %s; minimum compatible profile is %s (%d)\n", + profile_name ? profile_name : "unknown", profile, + av_get_pix_fmt_name(avctx->pix_fmt), + minimum_name ? minimum_name : "unknown", minimum); + return AVERROR(EINVAL); + } + + return 0; +} + static oapv_imgb_t *apv_imgb_create(AVCodecContext *avctx) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); @@ -180,22 +293,12 @@ fail: } /** - * The function returns a pointer to the object of the oapve_cdesc_t type. - * oapve_cdesc_t contains all encoder parameters that should be initialized before the encoder is used. + * Populate the liboapv configuration from AVCodecContext and encoder options. * - * The field values of the oapve_cdesc_t structure are populated based on: - * - the corresponding field values of the AvCodecConetxt structure, - * - the apv encoder specific option values, - * - * The order of processing input data and populating the apve_cdsc structure - * 1) first, the fields of the AVCodecContext structure corresponding to the provided input options are processed, - * (i.e -pix_fmt yuv422p -s:v 1920x1080 -r 30 -profile:v 0) - * 2) then apve-specific options added as AVOption to the apv AVCodec implementation - * (i.e -preset 0) - * - * Keep in mind that, there are options that can be set in different ways. - * In this case, please follow the above-mentioned order of processing. - * The most recent assignments overwrite the previous values. + * AVCodecContext fields are applied first, followed by liboapv private options + * and finally oapv-params. The APV profile defaults to the minimum profile + * implied by pix_fmt, and later overrides must remain compatible with that + * pixel format. * * @param[in] avctx codec context (AVCodecContext) * @param[out] cdsc contains all APV encoder encoder parameters that should be initialized before the encoder is use @@ -228,6 +331,13 @@ static int get_conf(AVCodecContext *avctx, oapve_cdesc_t *cdsc) cdsc->param[FRM_IDX].fps_den = avctx->time_base.num; } + cdsc->param[FRM_IDX].profile_idc = get_min_profile(avctx->pix_fmt); + if (avctx->profile != AV_PROFILE_UNKNOWN) { + ret = validate_profile(avctx, avctx->profile); + if (ret < 0) + return ret; + cdsc->param[FRM_IDX].profile_idc = avctx->profile; + } cdsc->param[FRM_IDX].preset = apv->preset_id; cdsc->param[FRM_IDX].qp = apv->qp; if (avctx->bit_rate / 1000 > INT_MAX || avctx->rc_max_rate / 1000 > INT_MAX) { @@ -275,6 +385,12 @@ static int get_conf(AVCodecContext *avctx, oapve_cdesc_t *cdsc) av_log(avctx, AV_LOG_WARNING, "Error parsing option '%s = %s'.\n", en->key, en->value); } + ret = validate_profile(avctx, cdsc->param[FRM_IDX].profile_idc); + if (ret < 0) + return ret; + + avctx->profile = cdsc->param[FRM_IDX].profile_idc; + return 0; } @@ -426,7 +542,7 @@ static av_cold int liboapve_close(AVCodecContext *avctx) { ApvEncContext *apv = avctx->priv_data; - for (int i = 0; i < apv->num_frames; i++) { + for (int i = 0; i < apv->ifrms.num_frms; i++) { if (apv->ifrms.frm[i].imgb != NULL) apv->ifrms.frm[i].imgb->release(apv->ifrms.frm[i].imgb); apv->ifrms.frm[i].imgb = NULL; diff --git a/libavcodec/magicyuv.c b/libavcodec/magicyuv.c index 46d474a24..04fb6cc14 100644 --- a/libavcodec/magicyuv.c +++ b/libavcodec/magicyuv.c @@ -225,7 +225,8 @@ static int magy_decode_slice10(AVCodecContext *avctx, void *tdata, s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0); dst += stride; } - lefttop = left = dst[0]; + if (1 + interlaced < height) + lefttop = left = dst[0]; for (k = 1 + interlaced; k < height; k++) { magicyuv_median_pred16(dst, dst - fake_stride, dst, width, &left, &lefttop, max); lefttop = left = dst[0]; @@ -553,6 +554,13 @@ static int magy_decode_frame(AVCodecContext *avctx, AVFrame *p, "invalid slice height: %d\n", s->slice_height); return AVERROR_INVALIDDATA; } + if (s->vshift[1] && (s->slice_height & ((1 << s->vshift[1]) - 1))) { + av_log(avctx, AV_LOG_ERROR, + "slice_height %d is not aligned to chroma vertical " + "subsampling (must be a multiple of %d)\n", + s->slice_height, 1 << s->vshift[1]); + return AVERROR_INVALIDDATA; + } bytestream2_skipu(&gb, 4); @@ -563,11 +571,11 @@ static int magy_decode_frame(AVCodecContext *avctx, AVFrame *p, return AVERROR_INVALIDDATA; } + if ((s->slice_height >> s->vshift[1]) <= s->interlaced) { + av_log(avctx, AV_LOG_ERROR, "impossible slice height\n"); + return AVERROR_INVALIDDATA; + } if (s->interlaced) { - if ((s->slice_height >> s->vshift[1]) < 2) { - av_log(avctx, AV_LOG_ERROR, "impossible slice height\n"); - return AVERROR_INVALIDDATA; - } if ((avctx->coded_height % s->slice_height) && ((avctx->coded_height % s->slice_height) >> s->vshift[1]) < 2) { av_log(avctx, AV_LOG_ERROR, "impossible height\n"); return AVERROR_INVALIDDATA; diff --git a/libavcodec/misc4.c b/libavcodec/misc4.c index d92c671d1..ac87ebd5c 100644 --- a/libavcodec/misc4.c +++ b/libavcodec/misc4.c @@ -57,6 +57,12 @@ static av_cold int misc4_init(AVCodecContext *avctx) { MISC4Context *s = avctx->priv_data; + if (avctx->sample_rate <= 0) + return AVERROR_INVALIDDATA; + + if (avctx->ch_layout.nb_channels != 1 && avctx->ch_layout.nb_channels != 2) + return AVERROR_INVALIDDATA; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; switch (avctx->sample_rate) { case 8000: diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 9c8b846a7..9266fd9d1 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1453,6 +1453,7 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s) int linesize[MAX_COMPONENTS]; GetBitContext mb_bitmask_gb = {0}; // initialize to silence gcc warning int bytes_per_pixel = 1 + (s->bits > 8); + int field_pos = -1; int ret; if (s->avctx->codec_id == AV_CODEC_ID_MXPEG) { @@ -1586,9 +1587,11 @@ next_field: if (s->interlaced && bytestream2_get_bytes_left(&s->gB) > 2 && bytestream2_tell(&s->gB) > 2 && + bytestream2_tell(&s->gB) != field_pos && s->gB.buffer[-2] == 0xFF && s->gB.buffer[-1] == 0xD1) { av_log(s->avctx, AV_LOG_DEBUG, "AVRn interlaced picture marker found\n"); + field_pos = bytestream2_tell(&s->gB); s->bottom_field ^= 1; goto next_field; diff --git a/libavcodec/mwsc.c b/libavcodec/mwsc.c index 0d4ee9791..8976376d4 100644 --- a/libavcodec/mwsc.c +++ b/libavcodec/mwsc.c @@ -65,6 +65,9 @@ static int rle_uncompress(GetByteContext *gb, PutByteContext *pb, GetByteContext } else if (run == 255) { int pos = bytestream2_tell_p(pb); + if (!gbp) + return AVERROR_INVALIDDATA; + bytestream2_seek(gbp, pos, SEEK_SET); if (pos + width - w < fill) @@ -128,11 +131,16 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, return ret; bytestream2_init(&gb, s->decomp_buf, zstream->total_out); - bytestream2_init(&gbp, s->prev_frame->data[0], avctx->height * s->prev_frame->linesize[0]); + if (s->prev_frame->data[0]) + bytestream2_init(&gbp, s->prev_frame->data[0], avctx->height * s->prev_frame->linesize[0]); bytestream2_init_writer(&pb, frame->data[0], avctx->height * frame->linesize[0]); - if (rle_uncompress(&gb, &pb, &gbp, avctx->width, avctx->height, avctx->width * 3, - frame->linesize[0], s->prev_frame->linesize[0])) + ret = rle_uncompress(&gb, &pb, s->prev_frame->data[0] ? &gbp : NULL, + avctx->width, avctx->height, avctx->width * 3, + frame->linesize[0], s->prev_frame->linesize[0]); + if (ret < 0) + return ret; + if (ret) frame->flags |= AV_FRAME_FLAG_KEY; else frame->flags &= ~AV_FRAME_FLAG_KEY; diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 392230526..5eab67a1f 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -263,8 +263,10 @@ static void nvenc_map_preset(NvencContext *ctx) static void nvenc_print_driver_requirement(AVCodecContext *avctx, int level) { -#if NVENCAPI_CHECK_VERSION(13, 1) +#if NVENCAPI_CHECK_VERSION(13, 2) const char *minver = "(unknown)"; +#elif NVENCAPI_CHECK_VERSION(13, 1) + const char *minver = "610.00"; #elif NVENCAPI_CHECK_VERSION(13, 0) const char *minver = "570.0"; #elif NVENCAPI_CHECK_VERSION(12, 2) @@ -2526,7 +2528,12 @@ static void nvenc_fill_time_code(AVCodecContext *avctx, const AVFrame *frame, NV unsigned hh, mm, ss, ff, drop; ff_timecode_set_smpte(&drop, &hh, &mm, &ss, &ff, avctx->framerate, tc[i + 1], 0, 0); +#ifdef NVENC_NEW_COUNTING_TYPE + time_code->clockTimestamp[i].countingTypeLSB = 0; + time_code->clockTimestamp[i].countingTypeMSB = 0; +#else time_code->clockTimestamp[i].countingType = 0; +#endif time_code->clockTimestamp[i].discontinuityFlag = 0; time_code->clockTimestamp[i].cntDroppedFrames = drop; time_code->clockTimestamp[i].nFrames = ff; diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index 069ba82bc..46f1d9f4c 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -111,6 +111,11 @@ typedef void ID3D11Device; #define NVENC_HAVE_MVHEVC #endif +// SDK 13.1 compile time feature checks +#if NVENCAPI_CHECK_VERSION(13, 1) +#define NVENC_NEW_COUNTING_TYPE +#endif + typedef struct NvencSurface { NV_ENC_INPUT_PTR input_surface; diff --git a/libavcodec/on2avc.c b/libavcodec/on2avc.c index 0a912cc30..41ada55e1 100644 --- a/libavcodec/on2avc.c +++ b/libavcodec/on2avc.c @@ -866,6 +866,12 @@ static int on2avc_decode_frame(AVCodecContext * avctx, AVFrame *frame, av_log(avctx, AV_LOG_ERROR, "No subframes present\n"); return AVERROR_INVALIDDATA; } + if (num_frames > INT_MAX / ON2AVC_SUBFRAME_SIZE) { + av_log(avctx, AV_LOG_ERROR, + "Too many subframes (%d); per-frame sample count overflows\n", + num_frames); + return AVERROR_INVALIDDATA; + } /* get output buffer */ frame->nb_samples = ON2AVC_SUBFRAME_SIZE * num_frames; diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 99e700207..ebfe2c3df 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -291,7 +291,9 @@ static const AVOption avcodec_options[] = { {"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT709 }, INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"}, {"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"}, {"gamma22", "BT.470 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA22 }, INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"}, +{"bt470m", "BT.470 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA22 }, INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"}, {"gamma28", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA28 }, INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"}, +{"bt470bg", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA28 }, INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"}, {"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"}, {"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"}, {"linear", "Linear", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LINEAR }, INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"}, diff --git a/libavcodec/prores_raw.c b/libavcodec/prores_raw.c index c1c05fd95..915ad54a5 100644 --- a/libavcodec/prores_raw.c +++ b/libavcodec/prores_raw.c @@ -414,6 +414,11 @@ static int decode_frame(AVCodecContext *avctx, /* Flags */ int flags = bytestream2_get_be16(&gb_hdr); int align = (flags >> 1) & 0x7; + if (align > 4) { + av_log(avctx, AV_LOG_ERROR, + "Invalid tile alignment %d (max 4)\n", align); + return AVERROR_INVALIDDATA; + } /* Quantization matrix */ if (flags & 1) diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c index 1958f36c9..68fc69961 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -415,8 +415,9 @@ static int rv10_decode_packet(AVCodecContext *avctx, const uint8_t *buf, H263DecContext *const h = &rv->h; int mb_count, mb_pos, left, start_mb_x, active_bits_size, ret; + if ((ret = init_get_bits8(&h->gb, buf, FFMAX(buf_size, buf_size2))) < 0) + return ret; active_bits_size = buf_size * 8; - init_get_bits(&h->gb, buf, FFMAX(buf_size, buf_size2) * 8); if (h->c.codec_id == AV_CODEC_ID_RV10) mb_count = rv10_decode_picture_header(h); else diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index f78b91e7d..6942cc2e2 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -1427,7 +1427,9 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int int mb_pos, slice_type; int res; - init_get_bits(gb, buf, buf_size*8); + res = init_get_bits8(gb, buf, buf_size); + if (res < 0) + return res; res = r->parse_slice_header(r, gb, &r->si); if(res < 0){ av_log(s->avctx, AV_LOG_ERROR, "Incorrect or unknown slice header\n"); @@ -1647,7 +1649,8 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, AVFrame *pict, av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n"); return AVERROR_INVALIDDATA; } - init_get_bits(&r->gb, buf+offset, (buf_size-offset)*8); + if ((ret = init_get_bits8(&r->gb, buf+offset, buf_size-offset)) < 0) + return ret; if (r->parse_slice_header(r, &r->gb, &si) < 0 || si.start) { av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n"); return AVERROR_INVALIDDATA; @@ -1777,7 +1780,9 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, AVFrame *pict, av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n"); break; } - init_get_bits(&r->gb, buf+offset1, (buf_size-offset1)*8); + ret = init_get_bits8(&r->gb, buf+offset1, buf_size-offset1); + if (ret < 0) + return ret; if (r->parse_slice_header(r, &r->gb, &si) < 0) { size = offset2 - offset; }else diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index fc07ec659..c566e3e5c 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -1228,6 +1228,9 @@ static int old_codec37(SANMVideoContext *ctx, GetByteContext *gb, int top, int l if (width > ctx->aligned_width) return AVERROR_INVALIDDATA; + if (FFALIGN(height, 4) > ctx->aligned_height) + return AVERROR_INVALIDDATA; + if (bytestream2_get_bytes_left(gb) < 16) return AVERROR_INVALIDDATA; @@ -1551,6 +1554,9 @@ static int old_codec47(SANMVideoContext *ctx, GetByteContext *gb, int top, int l if (width > ctx->aligned_width) return AVERROR_INVALIDDATA; + if (FFALIGN(height, 8) > ctx->aligned_height) + return AVERROR_INVALIDDATA; + if (bytestream2_get_bytes_left(gb) < 26) return AVERROR_INVALIDDATA; diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c index 5312d48e9..e92f08257 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -705,13 +705,15 @@ static int get_dc(SnowEncContext *enc, int mb_x, int mb_y, int plane_index) for(y2= FFMAX(y, 0); y2h) obmc_v += obmc[index - block_h*obmc_stride]; - if(x+block_w>w) obmc_v += obmc[index - block_w]; + if(y<0) obmc_v += obmc[index + block_h*obmc_stride]; + if(x<0) obmc_v += obmc[index + block_w]; + if(y+block_h>h && row-block_h >= 0) obmc_v += obmc[index - block_h*obmc_stride]; + if(x+block_w>w && col-block_w >= 0) obmc_v += obmc[index - block_w]; //FIXME precalculate this or simplify it somehow else d = -dst[index] + (1<<(FRAC_BITS-1)); @@ -723,6 +725,9 @@ static int get_dc(SnowEncContext *enc, int mb_x, int mb_y, int plane_index) } *b= backup; + if (!aa) + return 0; + return av_clip_uint8( ROUNDED_DIV((int64_t)ab<jpeg_avctx->flags = avctx->flags; ctx->jpeg_avctx->flags2 = avctx->flags2; ctx->jpeg_avctx->idct_algo = avctx->idct_algo; + ctx->jpeg_avctx->max_pixels = avctx->max_pixels; ret = avcodec_open2(ctx->jpeg_avctx, NULL, NULL); if (ret < 0) return ret; diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c index 454121cc7..1c1b4057a 100644 --- a/libavcodec/truespeech.c +++ b/libavcodec/truespeech.c @@ -323,6 +323,11 @@ static int truespeech_decode_frame(AVCodecContext *avctx, AVFrame *frame, "Too small input buffer (%d bytes), need at least 32 bytes\n", buf_size); return -1; } + if (iterations > INT_MAX / 240) { + av_log(avctx, AV_LOG_ERROR, + "Too large input buffer (%d bytes); per-block sample count overflows\n", buf_size); + return AVERROR_INVALIDDATA; + } /* get output buffer */ frame->nb_samples = iterations * 240; diff --git a/libavcodec/vc2enc_dwt.c b/libavcodec/vc2enc_dwt.c index 809f938e1..5fb2642c9 100644 --- a/libavcodec/vc2enc_dwt.c +++ b/libavcodec/vc2enc_dwt.c @@ -56,7 +56,7 @@ static void vc2_subband_dwt_97(VC2TransformContext *t, dwtcoef *data, ptrdiff_t stride, int width, int height) { int x, y; - dwtcoef *datal = data, *synth = t->buffer, *synthl = synth; + uint32_t *datal = (uint32_t *)data, *synth = (uint32_t *)t->buffer, *synthl = synth; const ptrdiff_t synth_width = width << 1; const ptrdiff_t synth_height = height << 1; @@ -75,21 +75,21 @@ static void vc2_subband_dwt_97(VC2TransformContext *t, dwtcoef *data, synthl = synth; for (y = 0; y < synth_height; y++) { /* Lifting stage 2. */ - synthl[1] -= (8*synthl[0] + 9*synthl[2] - synthl[4] + 8) >> 4; + synthl[1] -= (dwtcoef)(8*synthl[0] + 9*synthl[2] - synthl[4] + 8) >> 4; for (x = 1; x < width - 2; x++) - synthl[2*x + 1] -= (9*synthl[2*x] + 9*synthl[2*x + 2] - synthl[2*x + 4] - + synthl[2*x + 1] -= (dwtcoef)(9*synthl[2*x] + 9*synthl[2*x + 2] - synthl[2*x + 4] - synthl[2 * x - 2] + 8) >> 4; - synthl[synth_width - 1] -= (17*synthl[synth_width - 2] - + synthl[synth_width - 1] -= (dwtcoef)(17*synthl[synth_width - 2] - synthl[synth_width - 4] + 8) >> 4; - synthl[synth_width - 3] -= (8*synthl[synth_width - 2] + + synthl[synth_width - 3] -= (dwtcoef)(8*synthl[synth_width - 2] + 9*synthl[synth_width - 4] - synthl[synth_width - 6] + 8) >> 4; /* Lifting stage 1. */ - synthl[0] += (synthl[1] + synthl[1] + 2) >> 2; + synthl[0] += (dwtcoef)(synthl[1] + synthl[1] + 2) >> 2; for (x = 1; x < width - 1; x++) - synthl[2*x] += (synthl[2*x - 1] + synthl[2*x + 1] + 2) >> 2; + synthl[2*x] += (dwtcoef)(synthl[2*x - 1] + synthl[2*x + 1] + 2) >> 2; - synthl[synth_width - 2] += (synthl[synth_width - 3] + + synthl[synth_width - 2] += (dwtcoef)(synthl[synth_width - 3] + synthl[synth_width - 1] + 2) >> 2; synthl += synth_width; } @@ -97,13 +97,13 @@ static void vc2_subband_dwt_97(VC2TransformContext *t, dwtcoef *data, /* Vertical synthesis: Lifting stage 2. */ synthl = synth + synth_width; for (x = 0; x < synth_width; x++) - synthl[x] -= (8*synthl[x - synth_width] + 9*synthl[x + synth_width] - + synthl[x] -= (dwtcoef)(8*synthl[x - synth_width] + 9*synthl[x + synth_width] - synthl[x + 3 * synth_width] + 8) >> 4; synthl = synth + (synth_width << 1); for (y = 1; y < height - 2; y++) { for (x = 0; x < synth_width; x++) - synthl[x + synth_width] -= (9*synthl[x] + + synthl[x + synth_width] -= (dwtcoef)(9*synthl[x] + 9*synthl[x + 2 * synth_width] - synthl[x - 2 * synth_width] - synthl[x + 4 * synth_width] + 8) >> 4; @@ -112,36 +112,36 @@ static void vc2_subband_dwt_97(VC2TransformContext *t, dwtcoef *data, synthl = synth + (synth_height - 1) * synth_width; for (x = 0; x < synth_width; x++) { - synthl[x] -= (17*synthl[x - synth_width] - + synthl[x] -= (dwtcoef)(17*synthl[x - synth_width] - synthl[x - 3*synth_width] + 8) >> 4; - synthl[x - 2*synth_width] -= (9*synthl[x - 3*synth_width] + + synthl[x - 2*synth_width] -= (dwtcoef)(9*synthl[x - 3*synth_width] + 8*synthl[x - 1*synth_width] - synthl[x - 5*synth_width] + 8) >> 4; } /* Vertical synthesis: Lifting stage 1. */ synthl = synth; for (x = 0; x < synth_width; x++) - synthl[x] += (synthl[x + synth_width] + synthl[x + synth_width] + 2) >> 2; + synthl[x] += (dwtcoef)(synthl[x + synth_width] + synthl[x + synth_width] + 2) >> 2; synthl = synth + (synth_width << 1); for (y = 1; y < height - 1; y++) { for (x = 0; x < synth_width; x++) - synthl[x] += (synthl[x - synth_width] + synthl[x + synth_width] + 2) >> 2; + synthl[x] += (dwtcoef)(synthl[x - synth_width] + synthl[x + synth_width] + 2) >> 2; synthl += synth_width << 1; } synthl = synth + (synth_height - 2) * synth_width; for (x = 0; x < synth_width; x++) - synthl[x] += (synthl[x - synth_width] + synthl[x + synth_width] + 2) >> 2; + synthl[x] += (dwtcoef)(synthl[x - synth_width] + synthl[x + synth_width] + 2) >> 2; - deinterleave(data, stride, width, height, synth); + deinterleave(data, stride, width, height, (dwtcoef *)synth); } static void vc2_subband_dwt_53(VC2TransformContext *t, dwtcoef *data, ptrdiff_t stride, int width, int height) { int x, y; - dwtcoef *synth = t->buffer, *synthl = synth, *datal = data; + uint32_t *synth = (uint32_t *)t->buffer, *synthl = synth, *datal = (uint32_t *)data; const ptrdiff_t synth_width = width << 1; const ptrdiff_t synth_height = height << 1; @@ -161,16 +161,16 @@ static void vc2_subband_dwt_53(VC2TransformContext *t, dwtcoef *data, for (y = 0; y < synth_height; y++) { /* Lifting stage 2. */ for (x = 0; x < width - 1; x++) - synthl[2 * x + 1] -= (synthl[2 * x] + synthl[2 * x + 2] + 1) >> 1; + synthl[2 * x + 1] -= (dwtcoef)(synthl[2 * x] + synthl[2 * x + 2] + 1) >> 1; - synthl[synth_width - 1] -= (2*synthl[synth_width - 2] + 1) >> 1; + synthl[synth_width - 1] -= (dwtcoef)(2*synthl[synth_width - 2] + 1) >> 1; /* Lifting stage 1. */ - synthl[0] += (2*synthl[1] + 2) >> 2; + synthl[0] += (dwtcoef)(2*synthl[1] + 2) >> 2; for (x = 1; x < width - 1; x++) - synthl[2 * x] += (synthl[2 * x - 1] + synthl[2 * x + 1] + 2) >> 2; + synthl[2 * x] += (dwtcoef)(synthl[2 * x - 1] + synthl[2 * x + 1] + 2) >> 2; - synthl[synth_width - 2] += (synthl[synth_width - 3] + synthl[synth_width - 1] + 2) >> 2; + synthl[synth_width - 2] += (dwtcoef)(synthl[synth_width - 3] + synthl[synth_width - 1] + 2) >> 2; synthl += synth_width; } @@ -178,37 +178,37 @@ static void vc2_subband_dwt_53(VC2TransformContext *t, dwtcoef *data, /* Vertical synthesis: Lifting stage 2. */ synthl = synth + synth_width; for (x = 0; x < synth_width; x++) - synthl[x] -= (synthl[x - synth_width] + synthl[x + synth_width] + 1) >> 1; + synthl[x] -= (dwtcoef)(synthl[x - synth_width] + synthl[x + synth_width] + 1) >> 1; synthl = synth + (synth_width << 1); for (y = 1; y < height - 1; y++) { for (x = 0; x < synth_width; x++) - synthl[x + synth_width] -= (synthl[x] + synthl[x + synth_width * 2] + 1) >> 1; + synthl[x + synth_width] -= (dwtcoef)(synthl[x] + synthl[x + synth_width * 2] + 1) >> 1; synthl += (synth_width << 1); } synthl = synth + (synth_height - 1) * synth_width; for (x = 0; x < synth_width; x++) - synthl[x] -= (2*synthl[x - synth_width] + 1) >> 1; + synthl[x] -= (dwtcoef)(2*synthl[x - synth_width] + 1) >> 1; /* Vertical synthesis: Lifting stage 1. */ synthl = synth; for (x = 0; x < synth_width; x++) - synthl[x] += (2*synthl[synth_width + x] + 2) >> 2; + synthl[x] += (dwtcoef)(2*synthl[synth_width + x] + 2) >> 2; synthl = synth + (synth_width << 1); for (y = 1; y < height - 1; y++) { for (x = 0; x < synth_width; x++) - synthl[x] += (synthl[x + synth_width] + synthl[x - synth_width] + 2) >> 2; + synthl[x] += (dwtcoef)(synthl[x + synth_width] + synthl[x - synth_width] + 2) >> 2; synthl += (synth_width << 1); } synthl = synth + (synth_height - 2)*synth_width; for (x = 0; x < synth_width; x++) - synthl[x] += (synthl[x - synth_width] + synthl[x + synth_width] + 2) >> 2; + synthl[x] += (dwtcoef)(synthl[x - synth_width] + synthl[x + synth_width] + 2) >> 2; - deinterleave(data, stride, width, height, synth); + deinterleave(data, stride, width, height, (dwtcoef *)synth); } static av_always_inline void dwt_haar(VC2TransformContext *t, dwtcoef *data, @@ -216,7 +216,7 @@ static av_always_inline void dwt_haar(VC2TransformContext *t, dwtcoef *data, const int s) { int x, y; - dwtcoef *synth = t->buffer, *synthl = synth, *datal = data; + uint32_t *synth = (uint32_t *)t->buffer, *synthl = synth, *datal = (uint32_t *)data; const ptrdiff_t synth_width = width << 1; const ptrdiff_t synth_height = height << 1; @@ -225,7 +225,7 @@ static av_always_inline void dwt_haar(VC2TransformContext *t, dwtcoef *data, for (x = 0; x < synth_width; x += 2) { synthl[y*synth_width + x + 1] = (datal[y*stride + x + 1] - datal[y*stride + x]) * (1 << s); synthl[y*synth_width + x] = datal[y*stride + x + 0] * (1 << s) + - ((synthl[y*synth_width + x + 1] + 1) >> 1); + ((dwtcoef)(synthl[y*synth_width + x + 1] + 1) >> 1); } } @@ -235,11 +235,11 @@ static av_always_inline void dwt_haar(VC2TransformContext *t, dwtcoef *data, synthl[(y + 1)*synth_width + x] = synthl[(y + 1)*synth_width + x] - synthl[y*synth_width + x]; synthl[y*synth_width + x] = synthl[y*synth_width + x] + - ((synthl[(y + 1)*synth_width + x] + 1) >> 1); + ((dwtcoef)(synthl[(y + 1)*synth_width + x] + 1) >> 1); } } - deinterleave(data, stride, width, height, synth); + deinterleave(data, stride, width, height, (dwtcoef *)synth); } static void vc2_subband_dwt_haar(VC2TransformContext *t, dwtcoef *data, diff --git a/libavcodec/version.h b/libavcodec/version.h index b564e2d84..1e3be3422 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -30,7 +30,7 @@ #include "version_major.h" #define LIBAVCODEC_VERSION_MINOR 28 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MICRO 102 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavcodec/vulkan_encode.c b/libavcodec/vulkan_encode.c index b6f0b26f6..39c43300c 100644 --- a/libavcodec/vulkan_encode.c +++ b/libavcodec/vulkan_encode.c @@ -772,14 +772,6 @@ av_cold int ff_vulkan_encode_init(AVCodecContext *avctx, FFVulkanEncodeContext * return AVERROR(EINVAL); } - if ((ctx->enc_caps.supportedEncodeFeedbackFlags & feedback_flags) != - feedback_flags) { - av_log (avctx, AV_LOG_ERROR, - "Driver does not support required encode feedback flags " - "(BUFFER_OFFSET and BYTES_WRITTEN).\n"); - return AVERROR(ENOTSUP); - } - ctx->base.op = &vulkan_base_encode_ops; ctx->codec = codec; @@ -881,6 +873,14 @@ av_cold int ff_vulkan_encode_init(AVCodecContext *avctx, FFVulkanEncodeContext * return AVERROR_EXTERNAL; } + if ((ctx->enc_caps.supportedEncodeFeedbackFlags & feedback_flags) != + feedback_flags) { + av_log(avctx, AV_LOG_ERROR, + "Driver does not support required encode feedback flags " + "(BUFFER_OFFSET and BYTES_WRITTEN).\n"); + return AVERROR(ENOTSUP); + } + err = init_rc(avctx, ctx); if (err < 0) return err; diff --git a/libavcodec/x86/vorbisdsp.asm b/libavcodec/x86/vorbisdsp.asm index 9afe2eb35..815a1b211 100644 --- a/libavcodec/x86/vorbisdsp.asm +++ b/libavcodec/x86/vorbisdsp.asm @@ -41,8 +41,8 @@ align 16 mova m1, [angq+block_sizeq] xorps m2, m2 xorps m3, m3 - cmpleps m2, m0 ; m <= 0.0 - cmpleps m3, m1 ; a <= 0.0 + cmpltps m2, m0 ; m < 0.0 + cmpltps m3, m1 ; a < 0.0 andps m2, m5 ; keep only the sign bit xorps m1, m2 mova m4, m3 diff --git a/libavdevice/alsa.c b/libavdevice/alsa.c index cfdb28ff4..4fd1d3b32 100644 --- a/libavdevice/alsa.c +++ b/libavdevice/alsa.c @@ -381,8 +381,10 @@ int ff_alsa_get_device_list(AVDeviceInfoList *device_list, snd_pcm_stream_t stre ret = AVERROR(ENOMEM); goto fail; } - new_device->device_name = av_strdup(name); - if ((tmp = strrchr(descr, '\n')) && tmp[1]) + new_device->device_name = av_strdup(name ? name : ""); + if (!descr) + new_device->device_description = av_strdup(""); + else if ((tmp = strrchr(descr, '\n')) && tmp[1]) new_device->device_description = av_strdup(&tmp[1]); else new_device->device_description = av_strdup(descr); diff --git a/libavdevice/version.h b/libavdevice/version.h index 6db29e7d4..673a67089 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -30,7 +30,7 @@ #include "version_major.h" #define LIBAVDEVICE_VERSION_MINOR 3 -#define LIBAVDEVICE_VERSION_MICRO 101 +#define LIBAVDEVICE_VERSION_MICRO 102 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ LIBAVDEVICE_VERSION_MINOR, \ diff --git a/libavfilter/aap_template.c b/libavfilter/aap_template.c index 0e0580fb3..a8cb18f26 100644 --- a/libavfilter/aap_template.c +++ b/libavfilter/aap_template.c @@ -196,8 +196,8 @@ static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int n { AudioAPContext *s = ctx->priv; AVFrame *out = arg; - const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(out->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(out->ch_layout.nb_channels, jobnr + 1, nb_jobs); for (int c = start; c < end; c++) { const ftype *input = (const ftype *)s->frame[0]->extended_data[c]; diff --git a/libavfilter/adynamicequalizer_template.c b/libavfilter/adynamicequalizer_template.c index 4eb2489cd..a03d65641 100644 --- a/libavfilter/adynamicequalizer_template.c +++ b/libavfilter/adynamicequalizer_template.c @@ -269,8 +269,8 @@ static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int n const ftype tqfactor = s->tqfactor; const ftype itqfactor = ONE / tqfactor; const ftype fg = TAN(M_PI * tfrequency / sample_rate); - const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(in->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(in->ch_layout.nb_channels, jobnr + 1, nb_jobs); const int is_disabled = ctx->is_disabled; const int detection = s->detection; const int tftype = s->tftype; diff --git a/libavfilter/af_acrossover.c b/libavfilter/af_acrossover.c index fedf281d5..8b2786bae 100644 --- a/libavfilter/af_acrossover.c +++ b/libavfilter/af_acrossover.c @@ -397,8 +397,8 @@ static int filter_channels_## name(AVFilterContext *ctx, void *arg, int jobnr, i AudioCrossoverContext *s = ctx->priv; \ AVFrame *in = arg; \ AVFrame **frames = s->frames; \ - const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; \ - const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; \ + const int start = ff_slice_pos(in->ch_layout.nb_channels, jobnr, nb_jobs); \ + const int end = ff_slice_pos(in->ch_layout.nb_channels, jobnr + 1, nb_jobs); \ const int nb_samples = in->nb_samples; \ const int nb_outs = ctx->nb_outputs; \ const int first_order = s->first_order; \ diff --git a/libavfilter/af_adecorrelate.c b/libavfilter/af_adecorrelate.c index 8991bf207..40b1ab0af 100644 --- a/libavfilter/af_adecorrelate.c +++ b/libavfilter/af_adecorrelate.c @@ -161,8 +161,8 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo ThreadData *td = arg; AVFrame *out = td->out; AVFrame *in = td->in; - const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(in->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(in->ch_layout.nb_channels, jobnr + 1, nb_jobs); for (int ch = start; ch < end; ch++) s->filter_channel(ctx, ch, in, out); diff --git a/libavfilter/af_adenorm.c b/libavfilter/af_adenorm.c index 0d61eed1d..e05b15b03 100644 --- a/libavfilter/af_adenorm.c +++ b/libavfilter/af_adenorm.c @@ -188,8 +188,8 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo ThreadData *td = arg; AVFrame *out = td->out; AVFrame *in = td->in; - const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(in->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(in->ch_layout.nb_channels, jobnr + 1, nb_jobs); for (int ch = start; ch < end; ch++) { s->filter[s->type](ctx, out->extended_data[ch], diff --git a/libavfilter/af_adrc.c b/libavfilter/af_adrc.c index 9e3becdf2..690158e38 100644 --- a/libavfilter/af_adrc.c +++ b/libavfilter/af_adrc.c @@ -349,8 +349,8 @@ static int drc_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) AudioDRCContext *s = ctx->priv; AVFrame *in = s->in; AVFrame *out = arg; - const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(out->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(out->ch_layout.nb_channels, jobnr + 1, nb_jobs); for (int ch = start; ch < end; ch++) drc_channel(ctx, in, out, ch); diff --git a/libavfilter/af_aemphasis.c b/libavfilter/af_aemphasis.c index d35111f89..abc42207a 100644 --- a/libavfilter/af_aemphasis.c +++ b/libavfilter/af_aemphasis.c @@ -105,8 +105,8 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo ThreadData *td = arg; AVFrame *out = td->out; AVFrame *in = td->in; - const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(in->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(in->ch_layout.nb_channels, jobnr + 1, nb_jobs); for (int ch = start; ch < end; ch++) { const double *src = (const double *)in->extended_data[ch]; diff --git a/libavfilter/af_afftdn.c b/libavfilter/af_afftdn.c index e97dfe1f0..648651778 100644 --- a/libavfilter/af_afftdn.c +++ b/libavfilter/af_afftdn.c @@ -1052,8 +1052,8 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job { AudioFFTDeNoiseContext *s = ctx->priv; AVFrame *in = arg; - const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(in->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(in->ch_layout.nb_channels, jobnr + 1, nb_jobs); const int window_length = s->window_length; const double *window = s->window; diff --git a/libavfilter/af_afftfilt.c b/libavfilter/af_afftfilt.c index 08cdcae2f..921599cf4 100644 --- a/libavfilter/af_afftfilt.c +++ b/libavfilter/af_afftfilt.c @@ -233,8 +233,8 @@ static int tx_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { AFFTFiltContext *s = ctx->priv; const int channels = s->channels; - const int start = (channels * jobnr) / nb_jobs; - const int end = (channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(channels, jobnr, nb_jobs); + const int end = ff_slice_pos(channels, jobnr + 1, nb_jobs); for (int ch = start; ch < end; ch++) { AVComplexFloat *fft_in = s->fft_in[ch]; @@ -253,8 +253,8 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job const float *window_lut = s->window_func_lut; const float f = sqrtf(1.f - s->overlap); const int channels = s->channels; - const int start = (channels * jobnr) / nb_jobs; - const int end = (channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(channels, jobnr, nb_jobs); + const int end = ff_slice_pos(channels, jobnr + 1, nb_jobs); double values[VAR_VARS_NB]; memcpy(values, arg, sizeof(values)); diff --git a/libavfilter/af_afir.c b/libavfilter/af_afir.c index fa6b063e4..38dabc08c 100644 --- a/libavfilter/af_afir.c +++ b/libavfilter/af_afir.c @@ -156,8 +156,8 @@ static int fir_channel(AVFilterContext *ctx, AVFrame *out, int ch) static int fir_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { AVFrame *out = arg; - const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(out->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(out->ch_layout.nb_channels, jobnr + 1, nb_jobs); for (int ch = start; ch < end; ch++) fir_channel(ctx, out, ch); diff --git a/libavfilter/af_afreqshift.c b/libavfilter/af_afreqshift.c index 68969f2fd..b0f378173 100644 --- a/libavfilter/af_afreqshift.c +++ b/libavfilter/af_afreqshift.c @@ -292,8 +292,8 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo ThreadData *td = arg; AVFrame *out = td->out; AVFrame *in = td->in; - const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(in->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(in->ch_layout.nb_channels, jobnr + 1, nb_jobs); for (int ch = start; ch < end; ch++) s->filter_channel(ctx, ch, in, out); diff --git a/libavfilter/af_anequalizer.c b/libavfilter/af_anequalizer.c index 2f39e94cc..074d9bdc4 100644 --- a/libavfilter/af_anequalizer.c +++ b/libavfilter/af_anequalizer.c @@ -687,8 +687,8 @@ static int filter_channels(AVFilterContext *ctx, void *arg, { AudioNEqualizerContext *s = ctx->priv; AVFrame *buf = arg; - const int start = (buf->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (buf->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(buf->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(buf->ch_layout.nb_channels, jobnr + 1, nb_jobs); for (int i = 0; i < s->nb_filters; i++) { EqualizatorFilter *f = &s->filters[i]; diff --git a/libavfilter/af_apsyclip.c b/libavfilter/af_apsyclip.c index 35ef2cef1..cc604d943 100644 --- a/libavfilter/af_apsyclip.c +++ b/libavfilter/af_apsyclip.c @@ -532,8 +532,8 @@ static int psy_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { AudioPsyClipContext *s = ctx->priv; AVFrame *out = arg; - const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(out->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(out->ch_layout.nb_channels, jobnr + 1, nb_jobs); for (int ch = start; ch < end; ch++) psy_channel(ctx, s->in, out, ch); diff --git a/libavfilter/af_arnndn.c b/libavfilter/af_arnndn.c index 23eeb1785..5d516f0b1 100644 --- a/libavfilter/af_arnndn.c +++ b/libavfilter/af_arnndn.c @@ -1411,8 +1411,8 @@ static int rnnoise_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_j ThreadData *td = arg; AVFrame *in = td->in; AVFrame *out = td->out; - const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(out->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(out->ch_layout.nb_channels, jobnr + 1, nb_jobs); for (int ch = start; ch < end; ch++) { rnnoise_channel(s, &s->st[ch], diff --git a/libavfilter/af_asdr.c b/libavfilter/af_asdr.c index ea7494017..0d299f053 100644 --- a/libavfilter/af_asdr.c +++ b/libavfilter/af_asdr.c @@ -52,8 +52,8 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)\ AVFrame *u = s->cache[0]; \ AVFrame *v = s->cache[1]; \ const int channels = u->ch_layout.nb_channels; \ - const int start = (channels * jobnr) / nb_jobs; \ - const int end = (channels * (jobnr+1)) / nb_jobs; \ + const int start = ff_slice_pos(channels, jobnr, nb_jobs); \ + const int end = ff_slice_pos(channels, jobnr + 1, nb_jobs); \ const int nb_samples = u->nb_samples; \ \ for (int ch = start; ch < end; ch++) { \ @@ -85,8 +85,8 @@ static int sisdr_##name(AVFilterContext *ctx, void *arg,int jobnr,int nb_jobs)\ AVFrame *u = s->cache[0]; \ AVFrame *v = s->cache[1]; \ const int channels = u->ch_layout.nb_channels; \ - const int start = (channels * jobnr) / nb_jobs; \ - const int end = (channels * (jobnr+1)) / nb_jobs; \ + const int start = ff_slice_pos(channels, jobnr, nb_jobs); \ + const int end = ff_slice_pos(channels, jobnr + 1, nb_jobs); \ const int nb_samples = u->nb_samples; \ \ for (int ch = start; ch < end; ch++) { \ @@ -121,8 +121,8 @@ static int psnr_##name(AVFilterContext *ctx, void *arg, int jobnr,int nb_jobs)\ AVFrame *u = s->cache[0]; \ AVFrame *v = s->cache[1]; \ const int channels = u->ch_layout.nb_channels; \ - const int start = (channels * jobnr) / nb_jobs; \ - const int end = (channels * (jobnr+1)) / nb_jobs; \ + const int start = ff_slice_pos(channels, jobnr, nb_jobs); \ + const int end = ff_slice_pos(channels, jobnr + 1, nb_jobs); \ const int nb_samples = u->nb_samples; \ \ for (int ch = start; ch < end; ch++) { \ diff --git a/libavfilter/af_asoftclip.c b/libavfilter/af_asoftclip.c index 19923f2c3..3b183a7b1 100644 --- a/libavfilter/af_asoftclip.c +++ b/libavfilter/af_asoftclip.c @@ -410,8 +410,8 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo AVFrame *in = td->in; const int channels = td->channels; const int nb_samples = td->nb_samples; - const int start = (channels * jobnr) / nb_jobs; - const int end = (channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(channels, jobnr, nb_jobs); + const int end = ff_slice_pos(channels, jobnr + 1, nb_jobs); s->filter(s, (void **)out->extended_data, (const void **)in->extended_data, nb_samples, channels, start, end); diff --git a/libavfilter/af_aspectralstats.c b/libavfilter/af_aspectralstats.c index ac7da748e..b7ea65f67 100644 --- a/libavfilter/af_aspectralstats.c +++ b/libavfilter/af_aspectralstats.c @@ -438,8 +438,8 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job const float *window_func_lut = s->window_func_lut; AVFrame *in = arg; const int channels = s->nb_channels; - const int start = (channels * jobnr) / nb_jobs; - const int end = (channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(channels, jobnr, nb_jobs); + const int end = ff_slice_pos(channels, jobnr + 1, nb_jobs); const int offset = s->win_size - s->hop_size; for (int ch = start; ch < end; ch++) { diff --git a/libavfilter/af_astats.c b/libavfilter/af_astats.c index 6ef69ff10..3e75c7267 100644 --- a/libavfilter/af_astats.c +++ b/libavfilter/af_astats.c @@ -684,8 +684,8 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job const uint8_t * const * const data = (const uint8_t * const *)buf->extended_data; const int channels = s->nb_channels; const int samples = buf->nb_samples; - const int start = (buf->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (buf->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(buf->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(buf->ch_layout.nb_channels, jobnr + 1, nb_jobs); switch (inlink->format) { case AV_SAMPLE_FMT_DBLP: diff --git a/libavfilter/af_asubboost.c b/libavfilter/af_asubboost.c index 58135626b..b10139c69 100644 --- a/libavfilter/af_asubboost.c +++ b/libavfilter/af_asubboost.c @@ -108,8 +108,8 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo const double b2 = s->b2; const double a1 = -s->a1; const double a2 = -s->a2; - const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(in->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(in->ch_layout.nb_channels, jobnr + 1, nb_jobs); const int buffer_samples = s->buffer_samples; for (int ch = start; ch < end; ch++) { diff --git a/libavfilter/af_asupercut.c b/libavfilter/af_asupercut.c index 3e032d74b..621325e42 100644 --- a/libavfilter/af_asupercut.c +++ b/libavfilter/af_asupercut.c @@ -210,8 +210,8 @@ static int filter_channels_## name(AVFilterContext *ctx, void *arg, \ ThreadData *td = arg; \ AVFrame *out = td->out; \ AVFrame *in = td->in; \ - const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; \ - const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; \ + const int start = ff_slice_pos(in->ch_layout.nb_channels, jobnr, nb_jobs); \ + const int end = ff_slice_pos(in->ch_layout.nb_channels, jobnr + 1, nb_jobs); \ const double level = s->level; \ \ for (int ch = start; ch < end; ch++) { \ diff --git a/libavfilter/af_atilt.c b/libavfilter/af_atilt.c index b2cdef8fb..c2befcf55 100644 --- a/libavfilter/af_atilt.c +++ b/libavfilter/af_atilt.c @@ -125,8 +125,8 @@ static int filter_channels_## name(AVFilterContext *ctx, void *arg, \ ThreadData *td = arg; \ AVFrame *out = td->out; \ AVFrame *in = td->in; \ - const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; \ - const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; \ + const int start = ff_slice_pos(in->ch_layout.nb_channels, jobnr, nb_jobs); \ + const int end = ff_slice_pos(in->ch_layout.nb_channels, jobnr + 1, nb_jobs); \ const type level = s->level; \ \ for (int ch = start; ch < end; ch++) { \ diff --git a/libavfilter/af_biquads.c b/libavfilter/af_biquads.c index 565da3039..f62d87f4a 100644 --- a/libavfilter/af_biquads.c +++ b/libavfilter/af_biquads.c @@ -1242,8 +1242,8 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job AVFrame *buf = td->in; AVFrame *out_buf = td->out; BiquadsContext *s = ctx->priv; - const int start = (buf->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (buf->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(buf->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(buf->ch_layout.nb_channels, jobnr + 1, nb_jobs); int ch; for (ch = start; ch < end; ch++) { diff --git a/libavfilter/af_crystalizer.c b/libavfilter/af_crystalizer.c index 3cb5dc71d..ab6533571 100644 --- a/libavfilter/af_crystalizer.c +++ b/libavfilter/af_crystalizer.c @@ -65,8 +65,8 @@ static int filter_## inverse ##_## fmt ##_## clp(AVFilterContext *ctx, \ const int channels = td->channels; \ const type mult = td->mult; \ const type scale = one / (-mult + one); \ - const int start = (channels * jobnr) / nb_jobs; \ - const int end = (channels * (jobnr+1)) / nb_jobs; \ + const int start = ff_slice_pos(channels, jobnr, nb_jobs); \ + const int end = ff_slice_pos(channels, jobnr + 1, nb_jobs); \ \ if (packed) { \ type *prv = p[0]; \ diff --git a/libavfilter/af_dynaudnorm.c b/libavfilter/af_dynaudnorm.c index ddeedf625..938f99f75 100644 --- a/libavfilter/af_dynaudnorm.c +++ b/libavfilter/af_dynaudnorm.c @@ -579,8 +579,8 @@ static int update_gain_histories(AVFilterContext *ctx, void *arg, int jobnr, int DynamicAudioNormalizerContext *s = ctx->priv; AVFrame *analyze_frame = arg; const int channels = s->channels; - const int start = (channels * jobnr) / nb_jobs; - const int end = (channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(channels, jobnr, nb_jobs); + const int end = ff_slice_pos(channels, jobnr + 1, nb_jobs); for (int c = start; c < end; c++) update_gain_history(s, c, get_max_local_gain(s, analyze_frame, c)); @@ -824,8 +824,8 @@ static int amplify_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_j AVFrame *in = td->in; const int enabled = td->enabled; const int channels = s->channels; - const int start = (channels * jobnr) / nb_jobs; - const int end = (channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(channels, jobnr, nb_jobs); + const int end = ff_slice_pos(channels, jobnr + 1, nb_jobs); for (int ch = start; ch < end; ch++) amplify_channel(s, in, out, enabled, ch); diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c index de13f8f2d..0ca644766 100644 --- a/libavfilter/af_join.c +++ b/libavfilter/af_join.c @@ -469,7 +469,7 @@ static int try_push_frame(AVFilterContext *ctx) for (j = 0; j < nb_buffers; j++) if (s->buffers[j]->buffer == buf->buffer) break; - if (j == i) + if (j == nb_buffers) s->buffers[nb_buffers++] = buf; } diff --git a/libavfilter/af_surround.c b/libavfilter/af_surround.c index 6c973f518..4e23e422f 100644 --- a/libavfilter/af_surround.c +++ b/libavfilter/af_surround.c @@ -1261,8 +1261,8 @@ static int fft_channel(AVFilterContext *ctx, AVFrame *in, int ch) static int fft_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { AVFrame *in = arg; - const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(in->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(in->ch_layout.nb_channels, jobnr + 1, nb_jobs); for (int ch = start; ch < end; ch++) fft_channel(ctx, in, ch); @@ -1302,8 +1302,8 @@ static int ifft_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs { AudioSurroundContext *s = ctx->priv; AVFrame *out = arg; - const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(out->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(out->ch_layout.nb_channels, jobnr + 1, nb_jobs); for (int ch = start; ch < end; ch++) { if (s->upmix) diff --git a/libavfilter/anlms_template.c b/libavfilter/anlms_template.c index a8d1dbfe0..7a3992200 100644 --- a/libavfilter/anlms_template.c +++ b/libavfilter/anlms_template.c @@ -106,8 +106,8 @@ static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int n { AudioNLMSContext *s = ctx->priv; AVFrame *out = arg; - const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(out->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(out->ch_layout.nb_channels, jobnr + 1, nb_jobs); for (int c = start; c < end; c++) { const ftype *input = (const ftype *)s->frame[0]->extended_data[c]; diff --git a/libavfilter/arls_template.c b/libavfilter/arls_template.c index c67b48cf6..51c85ceda 100644 --- a/libavfilter/arls_template.c +++ b/libavfilter/arls_template.c @@ -133,8 +133,8 @@ static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int n { AudioRLSContext *s = ctx->priv; AVFrame *out = arg; - const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs; - const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(out->ch_layout.nb_channels, jobnr, nb_jobs); + const int end = ff_slice_pos(out->ch_layout.nb_channels, jobnr + 1, nb_jobs); for (int c = start; c < end; c++) { const ftype *input = (const ftype *)s->frame[0]->extended_data[c]; diff --git a/libavfilter/avf_avectorscope.c b/libavfilter/avf_avectorscope.c index 4e477627b..e20c00f75 100644 --- a/libavfilter/avf_avectorscope.c +++ b/libavfilter/avf_avectorscope.c @@ -201,8 +201,8 @@ static int fade(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) AudioVectorScopeContext *s = ctx->priv; const int linesize = s->outpicref->linesize[0]; const int height = s->outpicref->height; - const int slice_start = (height * jobnr ) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); if (s->fade[0] == 255 && s->fade[1] == 255 && s->fade[2] == 255) { for (int i = slice_start; i < slice_end; i++) diff --git a/libavfilter/avf_showcwt.c b/libavfilter/avf_showcwt.c index 839bdc798..4187aa3bb 100644 --- a/libavfilter/avf_showcwt.c +++ b/libavfilter/avf_showcwt.c @@ -446,8 +446,8 @@ static int draw(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const ptrdiff_t alinesize = s->outpicref->linesize[3]; const float log_factor = 1.f/logf(s->logarithmic_basis); const int count = s->frequency_band_count; - const int start = (count * jobnr) / nb_jobs; - const int end = (count * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(count, jobnr, nb_jobs); + const int end = ff_slice_pos(count, jobnr + 1, nb_jobs); const int nb_channels = s->nb_channels; const int iscale = s->intensity_scale; const int ihop_index = s->ihop_index; @@ -650,8 +650,8 @@ static int run_channel_cwt(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo const float scale = 1.f / input_padding_size; const int ihop_size = s->ihop_size; const int count = s->frequency_band_count; - const int start = (count * jobnr) / nb_jobs; - const int end = (count * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(count, jobnr, nb_jobs); + const int end = ff_slice_pos(count, jobnr + 1, nb_jobs); for (int y = start; y < end; y++) { AVComplexFloat *chout = ((AVComplexFloat *)s->ch_out->extended_data[y]) + ch * ihop_size; @@ -753,7 +753,7 @@ static int compute_kernel(AVFilterContext *ctx) } } - for (int n = b; n >= a; n--) { + for (int n = b - 1; n >= a; n--) { if (tkernel[n+range] != 0.f) { if (tkernel[n+range] > FLT_MIN) av_log(ctx, AV_LOG_DEBUG, "out of range kernel %g\n", tkernel[n+range]); @@ -808,6 +808,7 @@ static int config_output(AVFilterLink *outlink) float maximum_frequency = fminf(s->maximum_frequency, limit_frequency); float minimum_frequency = s->minimum_frequency; float scale = 1.f, factor; + double nb_samples; int ret; if (minimum_frequency >= maximum_frequency) { @@ -877,11 +878,11 @@ static int config_output(AVFilterLink *outlink) if (!s->frequency_band) return AVERROR(ENOMEM); - s->nb_consumed_samples = inlink->sample_rate * - frequency_band(s->frequency_band, - s->frequency_band_count, maximum_frequency - minimum_frequency, - minimum_frequency, s->frequency_scale, s->deviation); - s->nb_consumed_samples = FFMIN(s->nb_consumed_samples, 65536); + nb_samples = inlink->sample_rate * + frequency_band(s->frequency_band, + s->frequency_band_count, maximum_frequency - minimum_frequency, + minimum_frequency, s->frequency_scale, s->deviation); + s->nb_consumed_samples = av_clip(av_clipd(nb_samples, 1, 65536), 1, 65536); s->nb_threads = FFMIN(s->frequency_band_count, ff_filter_get_nb_threads(ctx)); s->nb_channels = inlink->ch_layout.nb_channels; @@ -1060,7 +1061,7 @@ static int output_frame(AVFilterContext *ctx) for (int p = 0; p < nb_planes; p++) { ptrdiff_t linesize = s->outpicref->linesize[p]; - for (int y = 0; y < s->sono_size; y++) { + for (int y = 0; y < s->sono_size - 1; y++) { uint8_t *dst = s->outpicref->data[p] + y * linesize; memmove(dst, dst + linesize, s->w); @@ -1140,7 +1141,7 @@ static int output_frame(AVFilterContext *ctx) case DIRECTION_RL: for (int p = 0; p < nb_planes; p++) { ptrdiff_t linesize = s->outpicref->linesize[p]; - const int size = s->w - s->pos; + const int size = FFMIN(s->pos + 1, s->sono_size); const int fill = p > 0 && p < 3 ? 128 : 0; for (int y = 0; y < s->h; y++) { @@ -1167,7 +1168,7 @@ static int output_frame(AVFilterContext *ctx) ptrdiff_t linesize = s->outpicref->linesize[p]; const int fill = p > 0 && p < 3 ? 128 : 0; - for (int y = s->h - s->pos; y >= 0; y--) { + for (int y = FFMIN(s->pos, s->sono_size - 1); y >= 0; y--) { uint8_t *dst = s->outpicref->data[p] + y * linesize; memset(dst, fill, s->w); @@ -1222,8 +1223,8 @@ static int run_channels_cwt_prepare(AVFilterContext *ctx, void *arg, int jobnr, { ShowCWTContext *s = ctx->priv; const int count = s->nb_channels; - const int start = (count * jobnr) / nb_jobs; - const int end = (count * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(count, jobnr, nb_jobs); + const int end = ff_slice_pos(count, jobnr + 1, nb_jobs); for (int ch = start; ch < end; ch++) run_channel_cwt_prepare(ctx, arg, jobnr, ch); diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c index 67bbc7715..2d87660fa 100644 --- a/libavfilter/avf_showspectrum.c +++ b/libavfilter/avf_showspectrum.c @@ -1143,6 +1143,11 @@ static int config_output(AVFilterLink *outlink) float scale = 1.f; ret = av_tx_init(&s->fft[i], &s->tx_fn, AV_TX_FLOAT_FFT, 0, fft_size << (!!s->stop), &scale, 0); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Unable to create FFT context. " + "The window size might be too high.\n"); + return ret; + } if (s->stop) { ret = av_tx_init(&s->ifft[i], &s->itx_fn, AV_TX_FLOAT_FFT, 1, fft_size << (!!s->stop), &scale, 0); if (ret < 0) { @@ -1151,11 +1156,6 @@ static int config_output(AVFilterLink *outlink) return ret; } } - if (ret < 0) { - av_log(ctx, AV_LOG_ERROR, "Unable to create FFT context. " - "The window size might be too high.\n"); - return ret; - } } s->magnitudes = av_calloc(s->nb_display_channels, sizeof(*s->magnitudes)); diff --git a/libavfilter/boxblur.c b/libavfilter/boxblur.c index 43c724dae..51029b93b 100644 --- a/libavfilter/boxblur.c +++ b/libavfilter/boxblur.c @@ -114,9 +114,9 @@ int ff_boxblur_eval_filter_params(AVFilterLink *inlink, #define CHECK_RADIUS_VAL(w_, h_, comp) \ if (comp->radius < 0 || \ - 2*comp->radius > FFMIN(w_, h_)) { \ + 2*comp->radius >= FFMIN(w_, h_)) { \ av_log(ctx, AV_LOG_ERROR, \ - "Invalid " #comp " radius value %d, must be >= 0 and <= %d\n", \ + "Invalid " #comp " radius value %d, must be >= 0 and < %d\n", \ comp->radius, FFMIN(w_, h_)/2); \ return AVERROR(EINVAL); \ } diff --git a/libavfilter/colorchannelmixer_template.c b/libavfilter/colorchannelmixer_template.c index bef57476a..aed5c59cf 100644 --- a/libavfilter/colorchannelmixer_template.c +++ b/libavfilter/colorchannelmixer_template.c @@ -54,8 +54,8 @@ static av_always_inline int fn(filter_slice_rgba_planar)(AVFilterContext *ctx, v AVFrame *out = td->out; const float pa = s->preserve_amount; const float max = (1 << depth) - 1; - const int slice_start = (out->height * jobnr) / nb_jobs; - const int slice_end = (out->height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(out->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(out->height, jobnr + 1, nb_jobs); const pixel *srcg = (const pixel *)(in->data[0] + slice_start * in->linesize[0]); const pixel *srcb = (const pixel *)(in->data[1] + slice_start * in->linesize[1]); const pixel *srcr = (const pixel *)(in->data[2] + slice_start * in->linesize[2]); @@ -172,8 +172,8 @@ static av_always_inline int fn(filter_slice_rgba_packed)(AVFilterContext *ctx, v AVFrame *out = td->out; const float pa = s->preserve_amount; const float max = (1 << depth) - 1; - const int slice_start = (out->height * jobnr) / nb_jobs; - const int slice_end = (out->height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(out->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(out->height, jobnr + 1, nb_jobs); const uint8_t roffset = s->rgba_map[R]; const uint8_t goffset = s->rgba_map[G]; const uint8_t boffset = s->rgba_map[B]; diff --git a/libavfilter/f_ebur128.c b/libavfilter/f_ebur128.c index 46ff702e6..e6c2132fc 100644 --- a/libavfilter/f_ebur128.c +++ b/libavfilter/f_ebur128.c @@ -445,15 +445,22 @@ static int config_audio_output(AVFilterLink *outlink) if (!ebur128->ch_weighting || !ebur128->dsp.y || !ebur128->dsp.z) return AVERROR(ENOMEM); -#define I400_BINS(x) ((x) * 4 / 10) +#define I400_BINS(x) ((x) * 2 / 5) #define I3000_BINS(x) ((x) * 3) + if (outlink->sample_rate > INT_MAX/3U || outlink->sample_rate < 3) + return AVERROR(EINVAL); + ebur128->i400.cache_size = I400_BINS(outlink->sample_rate); ebur128->i3000.cache_size = I3000_BINS(outlink->sample_rate); + size_t i400_count, i3000_count; + if (av_size_mult(nb_channels, ebur128->i400.cache_size, &i400_count) < 0 || i400_count > INT_MAX || + av_size_mult(nb_channels, ebur128->i3000.cache_size, &i3000_count) < 0 || i3000_count > INT_MAX) + return AVERROR(EINVAL); ebur128->i400.sum = av_calloc(nb_channels, sizeof(*ebur128->i400.sum)); ebur128->i3000.sum = av_calloc(nb_channels, sizeof(*ebur128->i3000.sum)); - ebur128->i400.cache = av_calloc(nb_channels * ebur128->i400.cache_size, sizeof(*ebur128->i400.cache)); - ebur128->i3000.cache = av_calloc(nb_channels * ebur128->i3000.cache_size, sizeof(*ebur128->i3000.cache)); + ebur128->i400.cache = av_calloc(i400_count, sizeof(*ebur128->i400.cache)); + ebur128->i3000.cache = av_calloc(i3000_count, sizeof(*ebur128->i3000.cache)); if (!ebur128->i400.sum || !ebur128->i3000.sum || !ebur128->i400.cache || !ebur128->i3000.cache) return AVERROR(ENOMEM); diff --git a/libavfilter/f_zmq.c b/libavfilter/f_zmq.c index 253e1d9cc..647ee3796 100644 --- a/libavfilter/f_zmq.c +++ b/libavfilter/f_zmq.c @@ -156,7 +156,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *ref) while (1) { char cmd_buf[1024]; - char *recv_buf, *send_buf; + char *recv_buf = NULL, *send_buf = NULL; int recv_buf_size; Command cmd = {0}; int ret; diff --git a/libavfilter/filters.h b/libavfilter/filters.h index a152be4d4..57540d769 100644 --- a/libavfilter/filters.h +++ b/libavfilter/filters.h @@ -750,6 +750,21 @@ int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, */ int ff_filter_get_nb_threads(AVFilterContext *ctx) av_pure; +/** + * Compute the boundary index for a slice when work of size total is split + * into nb_jobs slices. Returns the first index of slice jobnr, so the slice + * jobnr covers [ff_slice_pos(total, jobnr, nb_jobs), + * ff_slice_pos(total, jobnr + 1, nb_jobs)). + * + * The multiplication is performed in 64bit to avoid signed overflow of the + * total * jobnr intermediate that would occur for large dimensions and many + * slice threads. + */ +static inline int ff_slice_pos(int total, int jobnr, int nb_jobs) +{ + return (int)((int64_t)total * jobnr / nb_jobs); +} + /** * Send a frame of data to the next filter. * diff --git a/libavfilter/version.h b/libavfilter/version.h index 83931e11d..aa0bfc2df 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -32,7 +32,7 @@ #include "version_major.h" #define LIBAVFILTER_VERSION_MINOR 14 -#define LIBAVFILTER_VERSION_MICRO 101 +#define LIBAVFILTER_VERSION_MICRO 102 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_amplify.c b/libavfilter/vf_amplify.c index 7f18012a5..56d55873c 100644 --- a/libavfilter/vf_amplify.c +++ b/libavfilter/vf_amplify.c @@ -98,8 +98,8 @@ typedef struct ThreadData { const stype limit[2] = { s->llimit, s->hlimit }; \ \ for (int p = 0; p < s->nb_planes; p++) { \ - const int slice_start = (s->height[p] * jobnr) / nb_jobs; \ - const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(s->height[p], jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(s->height[p], jobnr + 1, nb_jobs); \ type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ ptrdiff_t dst_linesize = out->linesize[p] / sizeof(type); \ \ diff --git a/libavfilter/vf_atadenoise.c b/libavfilter/vf_atadenoise.c index f443d34de..7773df561 100644 --- a/libavfilter/vf_atadenoise.c +++ b/libavfilter/vf_atadenoise.c @@ -345,8 +345,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const float *weights = s->weights[p]; const int h = s->planeheight[p]; const int w = s->planewidth[p]; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const uint8_t *src = in->data[p] + slice_start * in->linesize[p]; uint8_t *dst = out->data[p] + slice_start * out->linesize[p]; const int thra = s->thra[p]; diff --git a/libavfilter/vf_backgroundkey.c b/libavfilter/vf_backgroundkey.c index f0a76b977..2a067fd8a 100644 --- a/libavfilter/vf_backgroundkey.c +++ b/libavfilter/vf_backgroundkey.c @@ -48,8 +48,8 @@ static int do_backgroundkey_slice(AVFilterContext *avctx, void *arg, int jobnr, { BackgroundkeyContext *s = avctx->priv; AVFrame *frame = arg; - const int slice_start = (frame->height * jobnr) / nb_jobs; - const int slice_end = (frame->height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); const int min_diff = (255 + 255 + 255) * s->similarity; const float blend = s->blend; const int hsub = s->hsub_log2; @@ -91,8 +91,8 @@ static int do_backgroundkey16_slice(AVFilterContext *avctx, void *arg, int jobnr { BackgroundkeyContext *s = avctx->priv; AVFrame *frame = arg; - const int slice_start = (frame->height * jobnr) / nb_jobs; - const int slice_end = (frame->height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); const int hsub = s->hsub_log2; const int vsub = s->vsub_log2; const int max = s->max; diff --git a/libavfilter/vf_bilateral.c b/libavfilter/vf_bilateral.c index cf62b2315..0a08a6d6d 100644 --- a/libavfilter/vf_bilateral.c +++ b/libavfilter/vf_bilateral.c @@ -157,8 +157,8 @@ static void bilateralh_##name(BilateralContext *s, AVFrame *out, AVFrame *in, \ { \ const int width = s->planewidth[plane]; \ const int height = s->planeheight[plane]; \ - const int slice_start = (height * jobnr) / nb_jobs; \ - const int slice_end = (height * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); \ const int src_linesize = in->linesize[plane] / sizeof(type); \ const type *src = (const type *)in->data[plane]; \ float *img_temp = s->img_temp[plane]; \ @@ -229,8 +229,8 @@ static void bilateralv_##name(BilateralContext *s, AVFrame *out, AVFrame *in, \ { \ const int width = s->planewidth[plane]; \ const int height = s->planeheight[plane]; \ - const int slice_start = (width * jobnr) / nb_jobs; \ - const int slice_end = (width * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(width, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(width, jobnr + 1, nb_jobs); \ const int src_linesize = in->linesize[plane] / sizeof(type); \ const type *src = (const type *)in->data[plane] + slice_start; \ float *img_out_f = s->img_out_f[plane] + slice_start; \ @@ -332,8 +332,8 @@ static void bilateralo_##name(BilateralContext *s, AVFrame *out, AVFrame *in, \ { \ const int width = s->planewidth[plane]; \ const int height = s->planeheight[plane]; \ - const int slice_start = (height * jobnr) / nb_jobs; \ - const int slice_end = (height * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); \ const int dst_linesize = out->linesize[plane] / sizeof(type); \ \ for (int i = slice_start; i < slice_end; i++) { \ @@ -401,8 +401,8 @@ static int bilateralo_planes(AVFilterContext *ctx, void *arg, if (!(s->planes & (1 << plane))) { if (out != in) { const int height = s->planeheight[plane]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const int width = s->planewidth[plane]; const int linesize = in->linesize[plane]; const int dst_linesize = out->linesize[plane]; diff --git a/libavfilter/vf_blackdetect.c b/libavfilter/vf_blackdetect.c index d39b2df00..30fc81c40 100644 --- a/libavfilter/vf_blackdetect.c +++ b/libavfilter/vf_blackdetect.c @@ -168,8 +168,8 @@ static int black_counter(AVFilterContext *ctx, void *arg, const int plane = s->alpha ? 3 : 0; const int linesize = in->linesize[plane]; const int h = in->height; - const int start = (h * jobnr) / nb_jobs; - const int end = (h * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(h, jobnr, nb_jobs); + const int end = ff_slice_pos(h, jobnr + 1, nb_jobs); s->counter[jobnr] = s->func(in->data[plane] + start * linesize, linesize, in->width, end - start, diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c index 39343f02c..fe98da604 100644 --- a/libavfilter/vf_blackframe.c +++ b/libavfilter/vf_blackframe.c @@ -68,8 +68,8 @@ static const enum AVPixelFormat pix_fmts[] = { static int blackframe_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { ThreadData *td = arg; - int slice_start = (td->height * jobnr) / nb_jobs; - int slice_end = (td->height * (jobnr+1)) / nb_jobs; + int slice_start = ff_slice_pos(td->height, jobnr, nb_jobs); + int slice_end = ff_slice_pos(td->height, jobnr + 1, nb_jobs); const uint8_t *p; unsigned int black_pixels_count = 0; diff --git a/libavfilter/vf_blend.c b/libavfilter/vf_blend.c index 07656f05b..21f4b1909 100644 --- a/libavfilter/vf_blend.c +++ b/libavfilter/vf_blend.c @@ -168,8 +168,8 @@ DEFINE_BLEND_EXPR(float, 32bit, 4) static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { ThreadData *td = arg; - int slice_start = (td->h * jobnr ) / nb_jobs; - int slice_end = (td->h * (jobnr+1)) / nb_jobs; + int slice_start = ff_slice_pos(td->h, jobnr, nb_jobs); + int slice_end = ff_slice_pos(td->h, jobnr + 1, nb_jobs); int height = slice_end - slice_start; const uint8_t *top = td->top->data[td->plane]; const uint8_t *bottom = td->bottom->data[td->plane]; diff --git a/libavfilter/vf_bm3d.c b/libavfilter/vf_bm3d.c index b482f7693..16f4d98ac 100644 --- a/libavfilter/vf_bm3d.c +++ b/libavfilter/vf_bm3d.c @@ -695,9 +695,9 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const int height = s->planeheight[plane]; const int block_pos_bottom = FFMAX(0, height - s->block_size); const int block_pos_right = FFMAX(0, width - s->block_size); - const int slice_start = (((height + block_step - 1) / block_step) * jobnr / nb_jobs) * block_step; + const int slice_start = ff_slice_pos((height + block_step - 1) / block_step, jobnr, nb_jobs) * block_step; const int slice_end = (jobnr == nb_jobs - 1) ? block_pos_bottom + block_step : - (((height + block_step - 1) / block_step) * (jobnr + 1) / nb_jobs) * block_step; + ff_slice_pos((height + block_step - 1) / block_step, jobnr + 1, nb_jobs) * block_step; memset(sc->num, 0, width * height * sizeof(float)); memset(sc->den, 0, width * height * sizeof(float)); diff --git a/libavfilter/vf_bwdif.c b/libavfilter/vf_bwdif.c index 67efc3a8c..dbe35a029 100644 --- a/libavfilter/vf_bwdif.c +++ b/libavfilter/vf_bwdif.c @@ -54,7 +54,7 @@ typedef struct ThreadData { // and the frame is a multiple of 4 high then filter_line will never be called static inline int job_start(const int jobnr, const int nb_jobs, const int h) { - return jobnr >= nb_jobs ? h : ((h * jobnr) / nb_jobs) & ~3; + return jobnr >= nb_jobs ? h : (ff_slice_pos(h, jobnr, nb_jobs)) & ~3; } static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) diff --git a/libavfilter/vf_cas.c b/libavfilter/vf_cas.c index 54d164fb7..0546b7219 100644 --- a/libavfilter/vf_cas.c +++ b/libavfilter/vf_cas.c @@ -52,8 +52,8 @@ static int cas_slice8(AVFilterContext *avctx, void *arg, int jobnr, int nb_jobs) AVFrame *in = s->in; for (int p = 0; p < s->nb_planes; p++) { - const int slice_start = (s->planeheight[p] * jobnr) / nb_jobs; - const int slice_end = (s->planeheight[p] * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(s->planeheight[p], jobnr, nb_jobs); + const int slice_end = ff_slice_pos(s->planeheight[p], jobnr + 1, nb_jobs); const int linesize = out->linesize[p]; const int in_linesize = in->linesize[p]; const int w = s->planewidth[p]; @@ -119,8 +119,8 @@ static int cas_slice16(AVFilterContext *avctx, void *arg, int jobnr, int nb_jobs AVFrame *in = s->in; for (int p = 0; p < s->nb_planes; p++) { - const int slice_start = (s->planeheight[p] * jobnr) / nb_jobs; - const int slice_end = (s->planeheight[p] * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(s->planeheight[p], jobnr, nb_jobs); + const int slice_end = ff_slice_pos(s->planeheight[p], jobnr + 1, nb_jobs); const int linesize = out->linesize[p] / 2; const int in_linesize = in->linesize[p] / 2; const int w = s->planewidth[p]; diff --git a/libavfilter/vf_chromakey.c b/libavfilter/vf_chromakey.c index e5a7ac15b..7ef75f2d0 100644 --- a/libavfilter/vf_chromakey.c +++ b/libavfilter/vf_chromakey.c @@ -116,8 +116,8 @@ static int do_chromakey_slice(AVFilterContext *avctx, void *arg, int jobnr, int { AVFrame *frame = arg; - const int slice_start = (frame->height * jobnr) / nb_jobs; - const int slice_end = (frame->height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); ChromakeyContext *ctx = avctx->priv; @@ -146,8 +146,8 @@ static int do_chromakey16_slice(AVFilterContext *avctx, void *arg, int jobnr, in { AVFrame *frame = arg; - const int slice_start = (frame->height * jobnr) / nb_jobs; - const int slice_end = (frame->height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); ChromakeyContext *ctx = avctx->priv; @@ -180,8 +180,8 @@ static int do_chromahold_slice(AVFilterContext *avctx, void *arg, int jobnr, int { ChromakeyContext *ctx = avctx->priv; AVFrame *frame = arg; - const int slice_start = ((frame->height >> ctx->vsub_log2) * jobnr) / nb_jobs; - const int slice_end = ((frame->height >> ctx->vsub_log2) * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(frame->height >> ctx->vsub_log2, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(frame->height >> ctx->vsub_log2, jobnr + 1, nb_jobs); int x, y, alpha; @@ -217,8 +217,8 @@ static int do_chromahold16_slice(AVFilterContext *avctx, void *arg, int jobnr, i { ChromakeyContext *ctx = avctx->priv; AVFrame *frame = arg; - const int slice_start = ((frame->height >> ctx->vsub_log2) * jobnr) / nb_jobs; - const int slice_end = ((frame->height >> ctx->vsub_log2) * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(frame->height >> ctx->vsub_log2, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(frame->height >> ctx->vsub_log2, jobnr + 1, nb_jobs); const int mid = ctx->mid; double max = ctx->max; diff --git a/libavfilter/vf_chromanr.c b/libavfilter/vf_chromanr.c index ba2c57cdf..dc79f3f4f 100644 --- a/libavfilter/vf_chromanr.c +++ b/libavfilter/vf_chromanr.c @@ -97,8 +97,8 @@ static int distance ## _slice##name(AVFilterContext *ctx, void *arg, const int thres_v = s->thres_v; \ const int h = s->planeheight[1]; \ const int w = s->planewidth[1]; \ - const int slice_start = (h * jobnr) / nb_jobs; \ - const int slice_end = (h * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); \ type *out_uptr = (type *)(out->data[1] + slice_start * out_ulinesize); \ type *out_vptr = (type *)(out->data[2] + slice_start * out_vlinesize); \ \ diff --git a/libavfilter/vf_chromashift.c b/libavfilter/vf_chromashift.c index f0449d597..29691afbd 100644 --- a/libavfilter/vf_chromashift.c +++ b/libavfilter/vf_chromashift.c @@ -64,8 +64,8 @@ static int smear_slice ## depth(AVFilterContext *ctx, void *arg, int jobnr, int const int crv = s->crv; \ const int h = s->height[1]; \ const int w = s->width[1]; \ - const int slice_start = (h * jobnr) / nb_jobs; \ - const int slice_end = (h * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); \ const type *su = (const type *)in->data[1]; \ const type *sv = (const type *)in->data[2]; \ type *du = (type *)out->data[1] + slice_start * ulinesize; \ @@ -106,8 +106,8 @@ static int wrap_slice ## depth(AVFilterContext *ctx, void *arg, int jobnr, int n const int crv = s->crv; \ const int h = s->height[1]; \ const int w = s->width[1]; \ - const int slice_start = (h * jobnr) / nb_jobs; \ - const int slice_end = (h * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); \ const type *su = (const type *)in->data[1]; \ const type *sv = (const type *)in->data[2]; \ type *du = (type *)out->data[1] + slice_start * ulinesize; \ @@ -169,8 +169,8 @@ static int rgbasmear_slice ## depth(AVFilterContext *ctx, void *arg, int jobnr, const int av = s->av; \ const int h = s->height[1]; \ const int w = s->width[1]; \ - const int slice_start = (h * jobnr) / nb_jobs; \ - const int slice_end = (h * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); \ const type *sr = (const type *)in->data[2]; \ const type *sg = (const type *)in->data[0]; \ const type *sb = (const type *)in->data[1]; \ @@ -236,8 +236,8 @@ static int rgbawrap_slice ## depth(AVFilterContext *ctx, void *arg, int jobnr, i const int av = s->av; \ const int h = s->height[1]; \ const int w = s->width[1]; \ - const int slice_start = (h * jobnr) / nb_jobs; \ - const int slice_end = (h * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); \ const type *sr = (const type *)in->data[2]; \ const type *sg = (const type *)in->data[0]; \ const type *sb = (const type *)in->data[1]; \ diff --git a/libavfilter/vf_colorbalance.c b/libavfilter/vf_colorbalance.c index 80e218d32..991692be3 100644 --- a/libavfilter/vf_colorbalance.c +++ b/libavfilter/vf_colorbalance.c @@ -153,8 +153,8 @@ static int color_balance8_p(AVFilterContext *ctx, void *arg, int jobnr, int nb_j ThreadData *td = arg; AVFrame *in = td->in; AVFrame *out = td->out; - const int slice_start = (out->height * jobnr) / nb_jobs; - const int slice_end = (out->height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(out->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(out->height, jobnr + 1, nb_jobs); const uint8_t *srcg = in->data[0] + slice_start * in->linesize[0]; const uint8_t *srcb = in->data[1] + slice_start * in->linesize[1]; const uint8_t *srcr = in->data[2] + slice_start * in->linesize[2]; @@ -206,8 +206,8 @@ static int color_balance16_p(AVFilterContext *ctx, void *arg, int jobnr, int nb_ ThreadData *td = arg; AVFrame *in = td->in; AVFrame *out = td->out; - const int slice_start = (out->height * jobnr) / nb_jobs; - const int slice_end = (out->height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(out->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(out->height, jobnr + 1, nb_jobs); const uint16_t *srcg = (const uint16_t *)in->data[0] + slice_start * in->linesize[0] / 2; const uint16_t *srcb = (const uint16_t *)in->data[1] + slice_start * in->linesize[1] / 2; const uint16_t *srcr = (const uint16_t *)in->data[2] + slice_start * in->linesize[2] / 2; @@ -261,8 +261,8 @@ static int color_balance8(AVFilterContext *ctx, void *arg, int jobnr, int nb_job AVFrame *in = td->in; AVFrame *out = td->out; AVFilterLink *outlink = ctx->outputs[0]; - const int slice_start = (out->height * jobnr) / nb_jobs; - const int slice_end = (out->height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(out->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(out->height, jobnr + 1, nb_jobs); const uint8_t *srcrow = in->data[0] + slice_start * in->linesize[0]; const uint8_t roffset = s->rgba_map[R]; const uint8_t goffset = s->rgba_map[G]; @@ -312,8 +312,8 @@ static int color_balance16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo AVFrame *in = td->in; AVFrame *out = td->out; AVFilterLink *outlink = ctx->outputs[0]; - const int slice_start = (out->height * jobnr) / nb_jobs; - const int slice_end = (out->height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(out->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(out->height, jobnr + 1, nb_jobs); const uint16_t *srcrow = (const uint16_t *)in->data[0] + slice_start * in->linesize[0] / 2; const uint8_t roffset = s->rgba_map[R]; const uint8_t goffset = s->rgba_map[G]; diff --git a/libavfilter/vf_colorconstancy.c b/libavfilter/vf_colorconstancy.c index 7251cf312..a00de84de 100644 --- a/libavfilter/vf_colorconstancy.c +++ b/libavfilter/vf_colorconstancy.c @@ -270,8 +270,8 @@ static int slice_get_derivative(AVFilterContext* ctx, void* arg, int jobnr, int if (dir == DIR_X) { /** Applying gauss horizontally along each row */ const uint8_t *src = in->data[plane]; - slice_start = (height * jobnr ) / nb_jobs; - slice_end = (height * (jobnr + 1)) / nb_jobs; + slice_start = ff_slice_pos(height, jobnr, nb_jobs); + slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); for (r = slice_start; r < slice_end; ++r) { for (c = 0; c < width; ++c) { @@ -285,8 +285,8 @@ static int slice_get_derivative(AVFilterContext* ctx, void* arg, int jobnr, int } else { /** Applying gauss vertically along each column */ const double *src = td->data[src_index][plane]; - slice_start = (width * jobnr ) / nb_jobs; - slice_end = (width * (jobnr + 1)) / nb_jobs; + slice_start = ff_slice_pos(width, jobnr, nb_jobs); + slice_end = ff_slice_pos(width, jobnr + 1, nb_jobs); for (c = slice_start; c < slice_end; ++c) { for (r = 0; r < height; ++r) { @@ -448,8 +448,8 @@ static int filter_slice_grey_edge(AVFilterContext* ctx, void* arg, int jobnr, in const int height = s->planeheight[plane]; const int width = s->planewidth[plane]; const int in_linesize = in->linesize[plane]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const uint8_t *img_data = in->data[plane]; const double *src = td->data[INDEX_NORM][plane]; double *dst = td->data[INDEX_DST][plane]; diff --git a/libavfilter/vf_colorcontrast.c b/libavfilter/vf_colorcontrast.c index 05f2ad567..61579e2e9 100644 --- a/libavfilter/vf_colorcontrast.c +++ b/libavfilter/vf_colorcontrast.c @@ -94,8 +94,8 @@ static int colorcontrast_slice8(AVFilterContext *ctx, void *arg, int jobnr, int AVFrame *frame = arg; const int width = frame->width; const int height = frame->height; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t glinesize = frame->linesize[0]; const ptrdiff_t blinesize = frame->linesize[1]; const ptrdiff_t rlinesize = frame->linesize[2]; @@ -148,8 +148,8 @@ static int colorcontrast_slice16(AVFilterContext *ctx, void *arg, int jobnr, int const float max = (1 << depth) - 1; const int width = frame->width; const int height = frame->height; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t glinesize = frame->linesize[0] / 2; const ptrdiff_t blinesize = frame->linesize[1] / 2; const ptrdiff_t rlinesize = frame->linesize[2] / 2; @@ -201,8 +201,8 @@ static int colorcontrast_slice8p(AVFilterContext *ctx, void *arg, int jobnr, int const int step = s->step; const int width = frame->width; const int height = frame->height; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t linesize = frame->linesize[0]; const uint8_t roffset = s->rgba_map[R]; const uint8_t goffset = s->rgba_map[G]; @@ -253,8 +253,8 @@ static int colorcontrast_slice16p(AVFilterContext *ctx, void *arg, int jobnr, in const float max = (1 << depth) - 1; const int width = frame->width; const int height = frame->height; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t linesize = frame->linesize[0] / 2; const uint8_t roffset = s->rgba_map[R]; const uint8_t goffset = s->rgba_map[G]; diff --git a/libavfilter/vf_colorcorrect.c b/libavfilter/vf_colorcorrect.c index 4249bd414..b6c3d0433 100644 --- a/libavfilter/vf_colorcorrect.c +++ b/libavfilter/vf_colorcorrect.c @@ -68,8 +68,8 @@ static int average_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_job const float imax = s->imax; const int width = s->planewidth[1]; const int height = s->planeheight[1]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t ulinesize = frame->linesize[1]; const ptrdiff_t vlinesize = frame->linesize[2]; const uint8_t *uptr = (const uint8_t *)frame->data[1] + slice_start * ulinesize; @@ -99,8 +99,8 @@ static int average_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo const float imax = s->imax; const int width = s->planewidth[1]; const int height = s->planeheight[1]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t ulinesize = frame->linesize[1] / 2; const ptrdiff_t vlinesize = frame->linesize[2] / 2; const uint16_t *uptr = (const uint16_t *)frame->data[1] + slice_start * ulinesize; @@ -130,8 +130,8 @@ static int minmax_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs const float imax = s->imax; const int width = s->planewidth[1]; const int height = s->planeheight[1]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t ulinesize = frame->linesize[1]; const ptrdiff_t vlinesize = frame->linesize[2]; const uint8_t *uptr = (const uint8_t *)frame->data[1] + slice_start * ulinesize; @@ -166,8 +166,8 @@ static int minmax_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb_job const float imax = s->imax; const int width = s->planewidth[1]; const int height = s->planeheight[1]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t ulinesize = frame->linesize[1] / 2; const ptrdiff_t vlinesize = frame->linesize[2] / 2; const uint16_t *uptr = (const uint16_t *)frame->data[1] + slice_start * ulinesize; @@ -322,8 +322,8 @@ static int colorcorrect_slice8(AVFilterContext *ctx, void *arg, int jobnr, int n const int chroma_h = s->chroma_h; const int width = s->planewidth[1]; const int height = s->planeheight[1]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t ylinesize = frame->linesize[0]; const ptrdiff_t ulinesize = frame->linesize[1]; const ptrdiff_t vlinesize = frame->linesize[2]; @@ -363,8 +363,8 @@ static int colorcorrect_slice16(AVFilterContext *ctx, void *arg, int jobnr, int const int chroma_h = s->chroma_h; const int width = s->planewidth[1]; const int height = s->planeheight[1]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t ylinesize = frame->linesize[0] / 2; const ptrdiff_t ulinesize = frame->linesize[1] / 2; const ptrdiff_t vlinesize = frame->linesize[2] / 2; diff --git a/libavfilter/vf_colordetect.c b/libavfilter/vf_colordetect.c index cfe7753ca..397e27811 100644 --- a/libavfilter/vf_colordetect.c +++ b/libavfilter/vf_colordetect.c @@ -132,8 +132,8 @@ static int detect_range(AVFilterContext *ctx, void *arg, ColorDetectContext *s = ctx->priv; const AVFrame *in = arg; const ptrdiff_t stride = in->linesize[0]; - const int y_start = (in->height * jobnr) / nb_jobs; - const int y_end = (in->height * (jobnr + 1)) / nb_jobs; + const int y_start = ff_slice_pos(in->height, jobnr, nb_jobs); + const int y_end = ff_slice_pos(in->height, jobnr + 1, nb_jobs); const int h_slice = y_end - y_start; if (s->dsp.detect_range(in->data[0] + y_start * stride, stride, @@ -151,8 +151,8 @@ static int detect_alpha(AVFilterContext *ctx, void *arg, const AVFrame *in = arg; const int w = in->width; const int h = in->height; - const int y_start = (h * jobnr) / nb_jobs; - const int y_end = (h * (jobnr + 1)) / nb_jobs; + const int y_start = ff_slice_pos(h, jobnr, nb_jobs); + const int y_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const int h_slice = y_end - y_start; const int nb_planes = (s->desc->flags & AV_PIX_FMT_FLAG_RGB) ? 3 : 1; diff --git a/libavfilter/vf_colorize.c b/libavfilter/vf_colorize.c index 1ab71b2b8..3d0c423bf 100644 --- a/libavfilter/vf_colorize.c +++ b/libavfilter/vf_colorize.c @@ -50,8 +50,8 @@ static int colorizey_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_j AVFrame *frame = arg; const int width = s->planewidth[0]; const int height = s->planeheight[0]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t ylinesize = frame->linesize[0]; uint8_t *yptr = frame->data[0] + slice_start * ylinesize; const int yv = s->c[0]; @@ -73,8 +73,8 @@ static int colorizey_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb_ AVFrame *frame = arg; const int width = s->planewidth[0]; const int height = s->planeheight[0]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t ylinesize = frame->linesize[0] / 2; uint16_t *yptr = (uint16_t *)frame->data[0] + slice_start * ylinesize; const int yv = s->c[0]; @@ -96,8 +96,8 @@ static int colorize_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo AVFrame *frame = arg; const int width = s->planewidth[1]; const int height = s->planeheight[1]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t ulinesize = frame->linesize[1]; const ptrdiff_t vlinesize = frame->linesize[2]; uint8_t *uptr = frame->data[1] + slice_start * ulinesize; @@ -124,8 +124,8 @@ static int colorize_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb_j AVFrame *frame = arg; const int width = s->planewidth[1]; const int height = s->planeheight[1]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t ulinesize = frame->linesize[1] / 2; const ptrdiff_t vlinesize = frame->linesize[2] / 2; uint16_t *uptr = (uint16_t *)frame->data[1] + slice_start * ulinesize; diff --git a/libavfilter/vf_colorkey.c b/libavfilter/vf_colorkey.c index 4781e53bb..4ad0b4c89 100644 --- a/libavfilter/vf_colorkey.c +++ b/libavfilter/vf_colorkey.c @@ -67,8 +67,8 @@ static int do_colorkey_slice##name(AVFilterContext *avctx, \ int jobnr, int nb_jobs) \ { \ AVFrame *frame = arg; \ - const int slice_start = (frame->height * jobnr) / nb_jobs; \ - const int slice_end = (frame->height * (jobnr + 1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); \ ColorkeyContext *ctx = avctx->priv; \ const float similarity = ctx->similarity; \ const float iblend = 1.f / ctx->blend; \ @@ -102,8 +102,8 @@ static int do_colorhold_slice##name(AVFilterContext *avctx, void *arg, \ int jobnr, int nb_jobs) \ { \ AVFrame *frame = arg; \ - const int slice_start = (frame->height * jobnr) / nb_jobs; \ - const int slice_end = (frame->height * (jobnr + 1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); \ ColorkeyContext *ctx = avctx->priv; \ const int depth = ctx->depth; \ const int max = ctx->max; \ diff --git a/libavfilter/vf_colorlevels.c b/libavfilter/vf_colorlevels.c index 5fa378ca3..8e5479d1d 100644 --- a/libavfilter/vf_colorlevels.c +++ b/libavfilter/vf_colorlevels.c @@ -106,8 +106,8 @@ typedef struct ThreadData { const int linesize = s->linesize; \ const int step = s->step; \ const int process_h = td->h; \ - const int slice_start = (process_h * jobnr ) / nb_jobs; \ - const int slice_end = (process_h * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(process_h, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(process_h, jobnr + 1, nb_jobs); \ const int src_linesize = td->src_linesize / sizeof(type); \ const int dst_linesize = td->dst_linesize / sizeof(type); \ const type *src_r = (const type *)(td->srcrow[R]) + src_linesize * slice_start; \ diff --git a/libavfilter/vf_colormap.c b/libavfilter/vf_colormap.c index e0afc471e..4680a7b50 100644 --- a/libavfilter/vf_colormap.c +++ b/libavfilter/vf_colormap.c @@ -309,8 +309,8 @@ static int colormap_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_job const int maps = s->nb_maps; const int width = out->width; const int height = out->height; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const int sr_linesize = in->linesize[2] / 4; const int dr_linesize = out->linesize[2] / 4; const int sg_linesize = in->linesize[0] / 4; diff --git a/libavfilter/vf_colormatrix.c b/libavfilter/vf_colormatrix.c index 04504cd3f..596548cea 100644 --- a/libavfilter/vf_colormatrix.c +++ b/libavfilter/vf_colormatrix.c @@ -209,8 +209,8 @@ static int process_slice_uyvy422(AVFilterContext *ctx, void *arg, int jobnr, int const int width = src->width*2; const int src_pitch = src->linesize[0]; const int dst_pitch = dst->linesize[0]; - const int slice_start = (height * jobnr ) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const unsigned char *srcp = src->data[0] + slice_start * src_pitch; unsigned char *dstp = dst->data[0] + slice_start * dst_pitch; const int c2 = td->c2; @@ -245,8 +245,8 @@ static int process_slice_yuv444p(AVFilterContext *ctx, void *arg, int jobnr, int AVFrame *dst = td->dst; const int height = src->height; const int width = src->width; - const int slice_start = (height * jobnr ) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const int src_pitchY = src->linesize[0]; const int src_pitchUV = src->linesize[1]; const unsigned char *srcpU = src->data[1] + slice_start * src_pitchUV; @@ -292,8 +292,8 @@ static int process_slice_yuv422p(AVFilterContext *ctx, void *arg, int jobnr, int AVFrame *dst = td->dst; const int height = src->height; const int width = src->width; - const int slice_start = (height * jobnr ) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const int src_pitchY = src->linesize[0]; const int src_pitchUV = src->linesize[1]; const unsigned char *srcpU = src->data[1] + slice_start * src_pitchUV; @@ -340,8 +340,8 @@ static int process_slice_yuv420p(AVFilterContext *ctx, void *arg, int jobnr, int AVFrame *dst = td->dst; const int height = FFALIGN(src->height, 2) >> 1; const int width = src->width; - const int slice_start = ((height * jobnr ) / nb_jobs) << 1; - const int slice_end = ((height * (jobnr+1)) / nb_jobs) << 1; + const int slice_start = (ff_slice_pos(height, jobnr, nb_jobs)) << 1; + const int slice_end = (ff_slice_pos(height, jobnr + 1, nb_jobs)) << 1; const int src_pitchY = src->linesize[0]; const int src_pitchUV = src->linesize[1]; const int dst_pitchY = dst->linesize[0]; diff --git a/libavfilter/vf_colortemperature.c b/libavfilter/vf_colortemperature.c index b56bf837f..1373c9e8c 100644 --- a/libavfilter/vf_colortemperature.c +++ b/libavfilter/vf_colortemperature.c @@ -109,8 +109,8 @@ static int temperature_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb const float mix = s->mix; const float preserve = s->preserve; const float *color = s->color; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t glinesize = frame->linesize[0]; const ptrdiff_t blinesize = frame->linesize[1]; const ptrdiff_t rlinesize = frame->linesize[2]; @@ -151,8 +151,8 @@ static int temperature_slice16(AVFilterContext *ctx, void *arg, int jobnr, int n const float preserve = s->preserve; const float mix = s->mix; const float *color = s->color; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t glinesize = frame->linesize[0] / sizeof(uint16_t); const ptrdiff_t blinesize = frame->linesize[1] / sizeof(uint16_t); const ptrdiff_t rlinesize = frame->linesize[2] / sizeof(uint16_t); @@ -192,8 +192,8 @@ static int temperature_slice32(AVFilterContext *ctx, void *arg, int jobnr, int n const float preserve = s->preserve; const float mix = s->mix; const float *color = s->color; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t glinesize = frame->linesize[0] / sizeof(float); const ptrdiff_t blinesize = frame->linesize[1] / sizeof(float); const ptrdiff_t rlinesize = frame->linesize[2] / sizeof(float); @@ -237,8 +237,8 @@ static int temperature_slice8p(AVFilterContext *ctx, void *arg, int jobnr, int n const uint8_t roffset = s->rgba_map[R]; const uint8_t goffset = s->rgba_map[G]; const uint8_t boffset = s->rgba_map[B]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t linesize = frame->linesize[0]; uint8_t *ptr = frame->data[0] + slice_start * linesize; @@ -277,8 +277,8 @@ static int temperature_slice16p(AVFilterContext *ctx, void *arg, int jobnr, int const uint8_t roffset = s->rgba_map[R]; const uint8_t goffset = s->rgba_map[G]; const uint8_t boffset = s->rgba_map[B]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t linesize = frame->linesize[0] / sizeof(uint16_t); uint16_t *ptr = (uint16_t *)frame->data[0] + slice_start * linesize; diff --git a/libavfilter/vf_convolution.c b/libavfilter/vf_convolution.c index 7a27bdba2..70cbe2847 100644 --- a/libavfilter/vf_convolution.c +++ b/libavfilter/vf_convolution.c @@ -322,17 +322,16 @@ static void filter16_3x3(uint8_t *dstp, int width, int x; for (x = 0; x < width; x++) { - int sum = AV_RN16A(&c[0][2 * x]) * matrix[0] + - AV_RN16A(&c[1][2 * x]) * matrix[1] + - AV_RN16A(&c[2][2 * x]) * matrix[2] + - AV_RN16A(&c[3][2 * x]) * matrix[3] + - AV_RN16A(&c[4][2 * x]) * matrix[4] + - AV_RN16A(&c[5][2 * x]) * matrix[5] + - AV_RN16A(&c[6][2 * x]) * matrix[6] + - AV_RN16A(&c[7][2 * x]) * matrix[7] + - AV_RN16A(&c[8][2 * x]) * matrix[8]; - sum = (int)(sum * rdiv + bias + 0.5f); - dst[x] = av_clip(sum, 0, peak); + unsigned sum = (unsigned)AV_RN16A(&c[0][2 * x]) * matrix[0] + + (unsigned)AV_RN16A(&c[1][2 * x]) * matrix[1] + + (unsigned)AV_RN16A(&c[2][2 * x]) * matrix[2] + + (unsigned)AV_RN16A(&c[3][2 * x]) * matrix[3] + + (unsigned)AV_RN16A(&c[4][2 * x]) * matrix[4] + + (unsigned)AV_RN16A(&c[5][2 * x]) * matrix[5] + + (unsigned)AV_RN16A(&c[6][2 * x]) * matrix[6] + + (unsigned)AV_RN16A(&c[7][2 * x]) * matrix[7] + + (unsigned)AV_RN16A(&c[8][2 * x]) * matrix[8]; + dst[x] = av_clip((int)sum * rdiv + bias + 0.5f, 0, peak); } } @@ -345,13 +344,13 @@ static void filter16_5x5(uint8_t *dstp, int width, int x; for (x = 0; x < width; x++) { - int i, sum = 0; + int i; + unsigned sum = 0; for (i = 0; i < 25; i++) - sum += AV_RN16A(&c[i][2 * x]) * matrix[i]; + sum += (unsigned)AV_RN16A(&c[i][2 * x]) * matrix[i]; - sum = (int)(sum * rdiv + bias + 0.5f); - dst[x] = av_clip(sum, 0, peak); + dst[x] = av_clip((int)sum * rdiv + bias + 0.5f, 0, peak); } } @@ -364,13 +363,13 @@ static void filter16_7x7(uint8_t *dstp, int width, int x; for (x = 0; x < width; x++) { - int i, sum = 0; + int i; + unsigned sum = 0; for (i = 0; i < 49; i++) - sum += AV_RN16A(&c[i][2 * x]) * matrix[i]; + sum += (unsigned)AV_RN16A(&c[i][2 * x]) * matrix[i]; - sum = (int)(sum * rdiv + bias + 0.5f); - dst[x] = av_clip(sum, 0, peak); + dst[x] = av_clip((int)sum * rdiv + bias + 0.5f, 0, peak); } } @@ -383,13 +382,13 @@ static void filter16_row(uint8_t *dstp, int width, int x; for (x = 0; x < width; x++) { - int i, sum = 0; + int i; + unsigned sum = 0; for (i = 0; i < 2 * radius + 1; i++) - sum += AV_RN16A(&c[i][2 * x]) * matrix[i]; + sum += (unsigned)AV_RN16A(&c[i][2 * x]) * matrix[i]; - sum = (int)(sum * rdiv + bias + 0.5f); - dst[x] = av_clip(sum, 0, peak); + dst[x] = av_clip((int)sum * rdiv + bias + 0.5f, 0, peak); } } @@ -398,7 +397,7 @@ static void filter16_column(uint8_t *dstp, int height, const uint8_t *c[], int peak, int radius, int dstride, int stride, int size) { - DECLARE_ALIGNED(64, int, sum)[16]; + DECLARE_ALIGNED(64, unsigned, sum)[16]; uint16_t *dst = (uint16_t *)dstp; const int width = FFMIN(16, size); @@ -407,12 +406,11 @@ static void filter16_column(uint8_t *dstp, int height, memset(sum, 0, sizeof(sum)); for (int i = 0; i < 2 * radius + 1; i++) { for (int off16 = 0; off16 < width; off16++) - sum[off16] += AV_RN16A(&c[i][0 + y * stride + off16 * 2]) * matrix[i]; + sum[off16] += (unsigned)AV_RN16A(&c[i][0 + y * stride + off16 * 2]) * matrix[i]; } for (int off16 = 0; off16 < width; off16++) { - sum[off16] = (int)(sum[off16] * rdiv + bias + 0.5f); - dst[off16] = av_clip(sum[off16], 0, peak); + dst[off16] = av_clip((int)sum[off16] * rdiv + bias + 0.5f, 0, peak); } dst += dstride / 2; } @@ -426,13 +424,13 @@ static void filter_7x7(uint8_t *dst, int width, int x; for (x = 0; x < width; x++) { - int i, sum = 0; + int i; + unsigned sum = 0; for (i = 0; i < 49; i++) - sum += c[i][x] * matrix[i]; + sum += (unsigned)c[i][x] * matrix[i]; - sum = (int)(sum * rdiv + bias + 0.5f); - dst[x] = av_clip_uint8(sum); + dst[x] = av_clip_uint8((int)sum * rdiv + bias + 0.5f); } } @@ -444,13 +442,13 @@ static void filter_5x5(uint8_t *dst, int width, int x; for (x = 0; x < width; x++) { - int i, sum = 0; + int i; + unsigned sum = 0; for (i = 0; i < 25; i++) - sum += c[i][x] * matrix[i]; + sum += (unsigned)c[i][x] * matrix[i]; - sum = (int)(sum * rdiv + bias + 0.5f); - dst[x] = av_clip_uint8(sum); + dst[x] = av_clip_uint8((int)sum * rdiv + bias + 0.5f); } } @@ -465,11 +463,10 @@ static void filter_3x3(uint8_t *dst, int width, int x; for (x = 0; x < width; x++) { - int sum = c0[x] * matrix[0] + c1[x] * matrix[1] + c2[x] * matrix[2] + - c3[x] * matrix[3] + c4[x] * matrix[4] + c5[x] * matrix[5] + - c6[x] * matrix[6] + c7[x] * matrix[7] + c8[x] * matrix[8]; - sum = (int)(sum * rdiv + bias + 0.5f); - dst[x] = av_clip_uint8(sum); + unsigned sum = (unsigned)c0[x] * matrix[0] + (unsigned)c1[x] * matrix[1] + (unsigned)c2[x] * matrix[2] + + (unsigned)c3[x] * matrix[3] + (unsigned)c4[x] * matrix[4] + (unsigned)c5[x] * matrix[5] + + (unsigned)c6[x] * matrix[6] + (unsigned)c7[x] * matrix[7] + (unsigned)c8[x] * matrix[8]; + dst[x] = av_clip_uint8((int)sum * rdiv + bias + 0.5f); } } @@ -481,13 +478,13 @@ static void filter_row(uint8_t *dst, int width, int x; for (x = 0; x < width; x++) { - int i, sum = 0; + int i; + unsigned sum = 0; for (i = 0; i < 2 * radius + 1; i++) - sum += c[i][x] * matrix[i]; + sum += (unsigned)c[i][x] * matrix[i]; - sum = (int)(sum * rdiv + bias + 0.5f); - dst[x] = av_clip_uint8(sum); + dst[x] = av_clip_uint8((int)sum * rdiv + bias + 0.5f); } } @@ -496,19 +493,18 @@ static void filter_column(uint8_t *dst, int height, const uint8_t *c[], int peak, int radius, int dstride, int stride, int size) { - DECLARE_ALIGNED(64, int, sum)[16]; + DECLARE_ALIGNED(64, unsigned, sum)[16]; for (int y = 0; y < height; y++) { memset(sum, 0, sizeof(sum)); for (int i = 0; i < 2 * radius + 1; i++) { for (int off16 = 0; off16 < 16; off16++) - sum[off16] += c[i][0 + y * stride + off16] * matrix[i]; + sum[off16] += (unsigned)c[i][0 + y * stride + off16] * matrix[i]; } for (int off16 = 0; off16 < 16; off16++) { - sum[off16] = (int)(sum[off16] * rdiv + bias + 0.5f); - dst[off16] = av_clip_uint8(sum[off16]); + dst[off16] = av_clip_uint8((int)sum[off16] * rdiv + bias + 0.5f); } dst += dstride; } @@ -582,8 +578,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const int dstride = out->linesize[plane]; const int sizeh = mode == MATRIX_COLUMN ? width : height; const int sizew = mode == MATRIX_COLUMN ? height : width; - const int slice_start = (sizeh * jobnr) / nb_jobs; - const int slice_end = (sizeh * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(sizeh, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(sizeh, jobnr + 1, nb_jobs); const float rdiv = s->rdiv[plane]; const float bias = s->bias[plane]; const uint8_t *src = in->data[plane]; diff --git a/libavfilter/vf_convolve.c b/libavfilter/vf_convolve.c index ea9cc4588..80f1c5284 100644 --- a/libavfilter/vf_convolve.c +++ b/libavfilter/vf_convolve.c @@ -189,8 +189,8 @@ static int fft_horizontal(AVFilterContext *ctx, void *arg, int jobnr, int nb_job AVComplexFloat *hdata_out = td->hdata_out; const int plane = td->plane; const int n = td->n; - int start = (n * jobnr) / nb_jobs; - int end = (n * (jobnr+1)) / nb_jobs; + int start = ff_slice_pos(n, jobnr, nb_jobs); + int end = ff_slice_pos(n, jobnr + 1, nb_jobs); int y; for (y = start; y < end; y++) { @@ -376,8 +376,8 @@ static int fft_vertical(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) AVComplexFloat *vdata_out = td->vdata_out; const int plane = td->plane; const int n = td->n; - int start = (n * jobnr) / nb_jobs; - int end = (n * (jobnr+1)) / nb_jobs; + int start = ff_slice_pos(n, jobnr, nb_jobs); + int end = ff_slice_pos(n, jobnr + 1, nb_jobs); int y, x; for (y = start; y < end; y++) { @@ -401,8 +401,8 @@ static int ifft_vertical(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs AVComplexFloat *vdata_in = td->vdata_in; const int plane = td->plane; const int n = td->n; - int start = (n * jobnr) / nb_jobs; - int end = (n * (jobnr+1)) / nb_jobs; + int start = ff_slice_pos(n, jobnr, nb_jobs); + int end = ff_slice_pos(n, jobnr + 1, nb_jobs); int y, x; for (y = start; y < end; y++) { @@ -425,8 +425,8 @@ static int ifft_horizontal(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo AVComplexFloat *hdata_in = td->hdata_in; const int plane = td->plane; const int n = td->n; - int start = (n * jobnr) / nb_jobs; - int end = (n * (jobnr+1)) / nb_jobs; + int start = ff_slice_pos(n, jobnr, nb_jobs); + int end = ff_slice_pos(n, jobnr + 1, nb_jobs); int y; for (y = start; y < end; y++) { @@ -518,8 +518,8 @@ static int complex_multiply(AVFilterContext *ctx, void *arg, int jobnr, int nb_j AVComplexFloat *filter = td->vdata_in; const float noise = s->noise; const int n = td->n; - int start = (n * jobnr) / nb_jobs; - int end = (n * (jobnr+1)) / nb_jobs; + int start = ff_slice_pos(n, jobnr, nb_jobs); + int end = ff_slice_pos(n, jobnr + 1, nb_jobs); int y, x; for (y = start; y < end; y++) { @@ -548,8 +548,8 @@ static int complex_xcorrelate(AVFilterContext *ctx, void *arg, int jobnr, int nb AVComplexFloat *filter = td->vdata_in; const int n = td->n; const float scale = 1.f / (n * n); - int start = (n * jobnr) / nb_jobs; - int end = (n * (jobnr+1)) / nb_jobs; + int start = ff_slice_pos(n, jobnr, nb_jobs); + int end = ff_slice_pos(n, jobnr + 1, nb_jobs); for (int y = start; y < end; y++) { int yn = y * n; @@ -578,8 +578,8 @@ static int complex_divide(AVFilterContext *ctx, void *arg, int jobnr, int nb_job AVComplexFloat *filter = td->vdata_in; const float noise = s->noise; const int n = td->n; - int start = (n * jobnr) / nb_jobs; - int end = (n * (jobnr+1)) / nb_jobs; + int start = ff_slice_pos(n, jobnr, nb_jobs); + int end = ff_slice_pos(n, jobnr + 1, nb_jobs); int y, x; for (y = start; y < end; y++) { diff --git a/libavfilter/vf_corr.c b/libavfilter/vf_corr.c index 7b87fa2c4..e3234bd43 100644 --- a/libavfilter/vf_corr.c +++ b/libavfilter/vf_corr.c @@ -101,8 +101,8 @@ static int sum_##name(AVFilterContext *ctx, void *arg, \ sizeof(type); \ const int h = s->planeheight[c]; \ const int w = s->planewidth[c]; \ - const int slice_start = (h * jobnr) / nb_jobs; \ - const int slice_end = (h * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); \ const type *src1 = (const type *)master->data[c] + \ linesize1 * slice_start; \ const type *src2 = (const type *)ref->data[c] + \ @@ -147,8 +147,8 @@ static int corr_##name(AVFilterContext *ctx, void *arg, \ const type *src2 = (const type *)ref->data[c]; \ const int h = s->planeheight[c]; \ const int w = s->planewidth[c]; \ - const int slice_start = (h * jobnr) / nb_jobs; \ - const int slice_end = (h * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); \ const float scale = 1.f / s->max[c]; \ const float mean1 = s->mean[c][0]; \ const float mean2 = s->mean[c][1]; \ diff --git a/libavfilter/vf_curves.c b/libavfilter/vf_curves.c index 1d4b2d3b6..4a7a51a3d 100644 --- a/libavfilter/vf_curves.c +++ b/libavfilter/vf_curves.c @@ -757,8 +757,8 @@ static int filter_slice_packed(AVFilterContext *ctx, void *arg, int jobnr, int n const uint8_t g = curves->rgba_map[G]; const uint8_t b = curves->rgba_map[B]; const uint8_t a = curves->rgba_map[A]; - const int slice_start = (in->height * jobnr ) / nb_jobs; - const int slice_end = (in->height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(in->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(in->height, jobnr + 1, nb_jobs); if (curves->is_16bit) { for (y = slice_start; y < slice_end; y++) { @@ -805,8 +805,8 @@ static int filter_slice_planar(AVFilterContext *ctx, void *arg, int jobnr, int n const uint8_t g = curves->rgba_map[G]; const uint8_t b = curves->rgba_map[B]; const uint8_t a = curves->rgba_map[A]; - const int slice_start = (in->height * jobnr ) / nb_jobs; - const int slice_end = (in->height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(in->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(in->height, jobnr + 1, nb_jobs); if (curves->is_16bit) { for (y = slice_start; y < slice_end; y++) { diff --git a/libavfilter/vf_datascope.c b/libavfilter/vf_datascope.c index 3b37fd162..8d96d92b5 100644 --- a/libavfilter/vf_datascope.c +++ b/libavfilter/vf_datascope.c @@ -194,8 +194,8 @@ static int filter_color2(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs const int W = (outlink->w - xoff) / (C * 10); const int H = (outlink->h - yoff) / (PP * 12); const char *format[4] = {"%02X\n", "%04X\n", "%03d\n", "%05d\n"}; - const int slice_start = (W * jobnr) / nb_jobs; - const int slice_end = (W * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(W, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(W, jobnr + 1, nb_jobs); int x, y, p; for (y = 0; y < H && (y + s->y < inlink->h); y++) { @@ -241,8 +241,8 @@ static int filter_color(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const int W = (outlink->w - xoff) / (C * 10); const int H = (outlink->h - yoff) / (PP * 12); const char *format[4] = {"%02X\n", "%04X\n", "%03d\n", "%05d\n"}; - const int slice_start = (W * jobnr) / nb_jobs; - const int slice_end = (W * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(W, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(W, jobnr + 1, nb_jobs); int x, y, p; for (y = 0; y < H && (y + s->y < inlink->h); y++) { @@ -284,8 +284,8 @@ static int filter_mono(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const int W = (outlink->w - xoff) / (C * 10); const int H = (outlink->h - yoff) / (PP * 12); const char *format[4] = {"%02X\n", "%04X\n", "%03d\n", "%05d\n"}; - const int slice_start = (W * jobnr) / nb_jobs; - const int slice_end = (W * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(W, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(W, jobnr + 1, nb_jobs); int x, y, p; for (y = 0; y < H && (y + s->y < inlink->h); y++) { diff --git a/libavfilter/vf_dctdnoiz.c b/libavfilter/vf_dctdnoiz.c index 9241b3a9e..90fa8ee6c 100644 --- a/libavfilter/vf_dctdnoiz.c +++ b/libavfilter/vf_dctdnoiz.c @@ -675,8 +675,8 @@ static int filter_slice(AVFilterContext *ctx, const ThreadData *td = arg; const int w = s->pr_width; const int h = s->pr_height; - const int slice_start = (h * jobnr ) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const int slice_start_ctx = FFMAX(slice_start - s->bsize + 1, 0); const int slice_end_ctx = FFMIN(slice_end, h - s->bsize + 1); const int slice_h = slice_end_ctx - slice_start_ctx; diff --git a/libavfilter/vf_deband.c b/libavfilter/vf_deband.c index 97bd33e20..2ff4fca6f 100644 --- a/libavfilter/vf_deband.c +++ b/libavfilter/vf_deband.c @@ -146,8 +146,8 @@ static int deband_8_c(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const int dst_linesize = out->linesize[p]; const int src_linesize = in->linesize[p]; const int thr = s->thr[p]; - const int start = (s->planeheight[p] * jobnr ) / nb_jobs; - const int end = (s->planeheight[p] * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(s->planeheight[p], jobnr, nb_jobs); + const int end = ff_slice_pos(s->planeheight[p], jobnr + 1, nb_jobs); const int w = s->planewidth[p] - 1; const int h = s->planeheight[p] - 1; @@ -187,8 +187,8 @@ static int deband_8_coupling_c(AVFilterContext *ctx, void *arg, int jobnr, int n ThreadData *td = arg; AVFrame *in = td->in; AVFrame *out = td->out; - const int start = (s->planeheight[0] * jobnr ) / nb_jobs; - const int end = (s->planeheight[0] * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(s->planeheight[0], jobnr, nb_jobs); + const int end = ff_slice_pos(s->planeheight[0], jobnr + 1, nb_jobs); int x, y, p; for (y = start; y < end; y++) { @@ -252,8 +252,8 @@ static int deband_16_coupling_c(AVFilterContext *ctx, void *arg, int jobnr, int ThreadData *td = arg; AVFrame *in = td->in; AVFrame *out = td->out; - const int start = (s->planeheight[0] * jobnr ) / nb_jobs; - const int end = (s->planeheight[0] * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(s->planeheight[0], jobnr, nb_jobs); + const int end = ff_slice_pos(s->planeheight[0], jobnr + 1, nb_jobs); int x, y, p, z; for (y = start; y < end; y++) { @@ -327,8 +327,8 @@ static int deband_16_c(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const int dst_linesize = out->linesize[p] / 2; const int src_linesize = in->linesize[p] / 2; const int thr = s->thr[p]; - const int start = (s->planeheight[p] * jobnr ) / nb_jobs; - const int end = (s->planeheight[p] * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(s->planeheight[p], jobnr, nb_jobs); + const int end = ff_slice_pos(s->planeheight[p], jobnr + 1, nb_jobs); const int w = s->planewidth[p] - 1; const int h = s->planeheight[p] - 1; diff --git a/libavfilter/vf_dedot.c b/libavfilter/vf_dedot.c index 69b92141d..c37626a34 100644 --- a/libavfilter/vf_dedot.c +++ b/libavfilter/vf_dedot.c @@ -84,8 +84,8 @@ static int dedotcrawl##name(AVFilterContext *ctx, void *arg, \ int p3_linesize = s->frames[3]->linesize[0] / div; \ int p4_linesize = s->frames[4]->linesize[0] / div; \ const int h = s->planeheight[0]; \ - int slice_start = (h * jobnr) / nb_jobs; \ - int slice_end = (h * (jobnr+1)) / nb_jobs; \ + int slice_start = ff_slice_pos(h, jobnr, nb_jobs); \ + int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); \ type *p0 = (type *)s->frames[0]->data[0]; \ type *p1 = (type *)s->frames[1]->data[0]; \ type *p3 = (type *)s->frames[3]->data[0]; \ @@ -159,8 +159,8 @@ static int derainbow##name(AVFilterContext *ctx, void *arg, \ AVFrame *out = td->out; \ const int plane = td->plane; \ const int h = s->planeheight[plane]; \ - int slice_start = (h * jobnr) / nb_jobs; \ - int slice_end = (h * (jobnr+1)) / nb_jobs; \ + int slice_start = ff_slice_pos(h, jobnr, nb_jobs); \ + int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); \ int src_linesize = s->frames[2]->linesize[plane] / div; \ int dst_linesize = out->linesize[plane] / div; \ int p0_linesize = s->frames[0]->linesize[plane] / div; \ diff --git a/libavfilter/vf_despill.c b/libavfilter/vf_despill.c index 25bdd1acd..2ecbab039 100644 --- a/libavfilter/vf_despill.c +++ b/libavfilter/vf_despill.c @@ -43,8 +43,8 @@ static int do_despill_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_j DespillContext *s = ctx->priv; AVFrame *frame = arg; const int ro = s->co[0], go = s->co[1], bo = s->co[2], ao = s->co[3]; - const int slice_start = (frame->height * jobnr) / nb_jobs; - const int slice_end = (frame->height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); const float brightness = s->brightness; const float redscale = s->redscale; const float greenscale = s->greenscale; diff --git a/libavfilter/vf_displace.c b/libavfilter/vf_displace.c index 3a860fc97..eef9a9970 100644 --- a/libavfilter/vf_displace.c +++ b/libavfilter/vf_displace.c @@ -90,8 +90,8 @@ static int displace_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo for (int plane = 0; plane < s->nb_planes; plane++) { const int h = s->height[plane]; const int w = s->width[plane]; - const int slice_start = (h * jobnr ) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const int dlinesize = out->linesize[plane]; const int slinesize = in->linesize[plane]; const int xlinesize = xin->linesize[plane]; @@ -171,8 +171,8 @@ static int displace_packed(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo const int step = s->step; const int h = s->height[0]; const int w = s->width[0]; - const int slice_start = (h * jobnr ) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const int dlinesize = out->linesize[0]; const int slinesize = in->linesize[0]; const int xlinesize = xin->linesize[0]; diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index 70f2209c8..70e4ff43f 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -735,11 +735,13 @@ static int load_glyph(AVFilterContext *ctx, Glyph **glyph_ptr, uint32_t code, in FT_Vector shift; struct AVTreeNode *node = NULL; int ret = 0; + int cached = 0; /* get glyph */ dummy.code = code; dummy.fontsize = s->fontsize; glyph = av_tree_find(s->glyphs, &dummy, glyph_cmp, NULL); + cached = !!glyph; if (!glyph) { if (FT_Load_Glyph(s->face, code, s->ft_load_flags)) { return AVERROR(EINVAL); @@ -756,11 +758,12 @@ static int load_glyph(AVFilterContext *ctx, Glyph **glyph_ptr, uint32_t code, in goto error; } if (s->borderw) { - glyph->border_glyph = glyph->glyph; - if (FT_Glyph_StrokeBorder(&glyph->border_glyph, s->stroker, 0, 0)) { + FT_Glyph tmp = glyph->glyph; + if (FT_Glyph_StrokeBorder(&tmp, s->stroker, 0, 0)) { ret = AVERROR_EXTERNAL; goto error; } + glyph->border_glyph = tmp; } /* measure text height to calculate text_height (or the maximum text height) */ FT_Glyph_Get_CBox(glyph->glyph, FT_GLYPH_BBOX_SUBPIXELS, &glyph->bbox); @@ -771,13 +774,15 @@ static int load_glyph(AVFilterContext *ctx, Glyph **glyph_ptr, uint32_t code, in goto error; } av_tree_insert(&s->glyphs, glyph, glyph_cmp, &node); + cached = 1; } else { if (s->borderw && !glyph->border_glyph) { - glyph->border_glyph = glyph->glyph; - if (FT_Glyph_StrokeBorder(&glyph->border_glyph, s->stroker, 0, 0)) { + FT_Glyph tmp = glyph->glyph; + if (FT_Glyph_StrokeBorder(&tmp, s->stroker, 0, 0)) { ret = AVERROR_EXTERNAL; goto error; } + glyph->border_glyph = tmp; } } @@ -795,11 +800,11 @@ static int load_glyph(AVFilterContext *ctx, Glyph **glyph_ptr, uint32_t code, in goto error; } glyph->bglyph[idx] = (FT_BitmapGlyph)tmp_glyph; - if (glyph->bglyph[idx]->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { - av_log(ctx, AV_LOG_ERROR, "Monocromatic (1bpp) fonts are not supported.\n"); - ret = AVERROR(EINVAL); - goto error; - } + } + if (glyph->bglyph[idx]->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { + av_log(ctx, AV_LOG_ERROR, "Monocromatic (1bpp) fonts are not supported.\n"); + ret = AVERROR(EINVAL); + goto error; } if (s->borderw && !glyph->border_bglyph[idx]) { FT_Glyph tmp_glyph = glyph->border_glyph; @@ -816,10 +821,13 @@ static int load_glyph(AVFilterContext *ctx, Glyph **glyph_ptr, uint32_t code, in return 0; error: - if (glyph && glyph->glyph) - FT_Done_Glyph(glyph->glyph); - - av_freep(&glyph); + if (glyph && !cached) { + if (glyph->border_glyph && glyph->border_glyph != glyph->glyph) + FT_Done_Glyph(glyph->border_glyph); + if (glyph->glyph) + FT_Done_Glyph(glyph->glyph); + av_freep(&glyph); + } av_freep(&node); return ret; } @@ -1085,10 +1093,10 @@ static int glyph_enu_border_free(void *opaque, void *elem) if (glyph->border_glyph != NULL) { for (int t = 0; t < 16; ++t) { - if (glyph->border_bglyph[t] != NULL) { - FT_Done_Glyph((FT_Glyph)glyph->border_bglyph[t]); - glyph->border_bglyph[t] = NULL; - } + FT_Glyph bbg = (FT_Glyph)glyph->border_bglyph[t]; + if (bbg && bbg != glyph->border_glyph) + FT_Done_Glyph(bbg); + glyph->border_bglyph[t] = NULL; } FT_Done_Glyph(glyph->border_glyph); glyph->border_glyph = NULL; @@ -1100,16 +1108,17 @@ static int glyph_enu_free(void *opaque, void *elem) { Glyph *glyph = elem; - FT_Done_Glyph(glyph->glyph); - FT_Done_Glyph(glyph->border_glyph); for (int t = 0; t < 16; ++t) { - if (glyph->bglyph[t] != NULL) { - FT_Done_Glyph((FT_Glyph)glyph->bglyph[t]); - } - if (glyph->border_bglyph[t] != NULL) { - FT_Done_Glyph((FT_Glyph)glyph->border_bglyph[t]); - } + FT_Glyph bg = (FT_Glyph)glyph->bglyph[t]; + FT_Glyph bbg = (FT_Glyph)glyph->border_bglyph[t]; + if (bg && bg != glyph->glyph && bg != glyph->border_glyph) + FT_Done_Glyph(bg); + if (bbg && bbg != glyph->glyph && bbg != glyph->border_glyph) + FT_Done_Glyph(bbg); } + if (glyph->border_glyph && glyph->border_glyph != glyph->glyph) + FT_Done_Glyph(glyph->border_glyph); + FT_Done_Glyph(glyph->glyph); av_free(elem); return 0; } @@ -1362,23 +1371,25 @@ static int draw_glyphs(AVFilterContext *ctx, AVFrame *frame, static int shape_text_hb(DrawTextContext *s, HarfbuzzData* hb, const char* text, int textLen) { hb->buf = hb_buffer_create(); - if(!hb_buffer_allocation_successful(hb->buf)) { - return AVERROR(ENOMEM); - } + if(!hb_buffer_allocation_successful(hb->buf)) + goto fail; hb_buffer_set_direction(hb->buf, HB_DIRECTION_LTR); hb_buffer_set_script(hb->buf, HB_SCRIPT_LATIN); hb_buffer_set_language(hb->buf, hb_language_from_string("en", -1)); hb_buffer_guess_segment_properties(hb->buf); hb->font = hb_ft_font_create_referenced(s->face); - if(hb->font == NULL) { - return AVERROR(ENOMEM); - } + if(hb->font == NULL) + goto fail; hb_buffer_add_utf8(hb->buf, text, textLen, 0, -1); hb_shape(hb->font, hb->buf, NULL, 0); hb->glyph_info = hb_buffer_get_glyph_infos(hb->buf, &hb->glyph_count); hb->glyph_pos = hb_buffer_get_glyph_positions(hb->buf, &hb->glyph_count); return 0; +fail: + hb_buffer_destroy(hb->buf); + hb->buf = NULL; + return AVERROR(ENOMEM); } static void hb_destroy(HarfbuzzData *hb) @@ -1551,6 +1562,15 @@ continue_on_failed2: done: av_free(textdup); + if (ret < 0) { + if (s->lines) { + for (int l = 0; l < s->line_count; ++l) + hb_destroy(&s->lines[l].hb_data); + } + av_freep(&s->lines); + av_freep(&s->tab_clusters); + s->line_count = 0; + } return ret; } @@ -1741,7 +1761,7 @@ static int draw_text(AVFilterContext *ctx, AVFrame *frame) ret = load_glyph(ctx, &glyph, hb->glyph_info[t].codepoint, shift_x64, shift_y64); if (ret != 0) { - return ret; + goto fail; } g_info->code = hb->glyph_info[t].codepoint; g_info->x = (x64 + true_x) >> 6; @@ -1803,23 +1823,25 @@ static int draw_text(AVFilterContext *ctx, AVFrame *frame) if (s->shadowx || s->shadowy) { if ((ret = draw_glyphs(ctx, frame, &shadowcolor, &metrics, s->shadowx, s->shadowy, s->borderw)) < 0) { - return ret; + goto fail; } } if (s->borderw) { if ((ret = draw_glyphs(ctx, frame, &bordercolor, &metrics, 0, 0, s->borderw)) < 0) { - return ret; + goto fail; } } if ((ret = draw_glyphs(ctx, frame, &fontcolor, &metrics, 0, 0, 0)) < 0) { - return ret; + goto fail; } } + ret = 0; +fail: // FREE data structures for (int l = 0; l < s->line_count; ++l) { TextLine *line = &s->lines[l]; @@ -1828,8 +1850,9 @@ static int draw_text(AVFilterContext *ctx, AVFrame *frame) } av_freep(&s->lines); av_freep(&s->tab_clusters); + s->line_count = 0; - return 0; + return ret; } static int filter_frame(AVFilterLink *inlink, AVFrame *frame) diff --git a/libavfilter/vf_epx.c b/libavfilter/vf_epx.c index af40917b6..96b41a34b 100644 --- a/libavfilter/vf_epx.c +++ b/libavfilter/vf_epx.c @@ -48,8 +48,8 @@ static int epx2_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) ThreadData *td = arg; const AVFrame *in = td->in; AVFrame *out = td->out; - const int slice_start = (in->height * jobnr ) / nb_jobs; - const int slice_end = (in->height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(in->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(in->height, jobnr + 1, nb_jobs); for (int p = 0; p < 1; p++) { const int width = in->width; @@ -115,8 +115,8 @@ static int epx3_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) ThreadData *td = arg; const AVFrame *in = td->in; AVFrame *out = td->out; - const int slice_start = (in->height * jobnr ) / nb_jobs; - const int slice_end = (in->height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(in->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(in->height, jobnr + 1, nb_jobs); for (int p = 0; p < 1; p++) { const int width = in->width; diff --git a/libavfilter/vf_estdif.c b/libavfilter/vf_estdif.c index b8289a6e9..ae61e2bce 100644 --- a/libavfilter/vf_estdif.c +++ b/libavfilter/vf_estdif.c @@ -354,8 +354,8 @@ static int deinterlace_slice(AVFilterContext *ctx, void *arg, const int height = s->planeheight[plane]; const int src_linesize = in->linesize[plane]; const int dst_linesize = out->linesize[plane]; - const int start = (height * jobnr) / nb_jobs; - const int end = (height * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(height, jobnr, nb_jobs); + const int end = ff_slice_pos(height, jobnr + 1, nb_jobs); const uint8_t *prev_line, *prev2_line, *next_line, *next2_line, *in_line; const uint8_t *prev3_line, *next3_line; uint8_t *out_line; diff --git a/libavfilter/vf_exposure.c b/libavfilter/vf_exposure.c index 833aa953d..486659160 100644 --- a/libavfilter/vf_exposure.c +++ b/libavfilter/vf_exposure.c @@ -46,8 +46,8 @@ static int exposure_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_job ThreadData *td = arg; const int width = td->out->width; const int height = td->out->height; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const float black = s->black; const float scale = s->scale; diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c index efe0ea380..08ef73378 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -253,8 +253,8 @@ static int filter_slice_rgb(AVFilterContext *ctx, void *arg, int jobnr, { FadeContext *s = ctx->priv; AVFrame *frame = arg; - int slice_start = (frame->height * jobnr ) / nb_jobs; - int slice_end = (frame->height * (jobnr+1)) / nb_jobs; + int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); + int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); if (s->is_planar && s->alpha) filter_rgb_planar(s, frame, slice_start, slice_end, 1); @@ -273,8 +273,8 @@ static int filter_slice_luma(AVFilterContext *ctx, void *arg, int jobnr, { FadeContext *s = ctx->priv; AVFrame *frame = arg; - int slice_start = (frame->height * jobnr ) / nb_jobs; - int slice_end = (frame->height * (jobnr+1)) / nb_jobs; + int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); + int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); int i, j; for (int k = 0; k < 1 + 2 * (s->is_planar && s->is_rgb); k++) { @@ -298,8 +298,8 @@ static int filter_slice_luma16(AVFilterContext *ctx, void *arg, int jobnr, { FadeContext *s = ctx->priv; AVFrame *frame = arg; - int slice_start = (frame->height * jobnr ) / nb_jobs; - int slice_end = (frame->height * (jobnr+1)) / nb_jobs; + int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); + int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); int i, j; for (int k = 0; k < 1 + 2 * (s->is_planar && s->is_rgb); k++) { @@ -326,8 +326,8 @@ static int filter_slice_chroma(AVFilterContext *ctx, void *arg, int jobnr, int i, j, plane; const int width = AV_CEIL_RSHIFT(frame->width, s->hsub); const int height= AV_CEIL_RSHIFT(frame->height, s->vsub); - int slice_start = (height * jobnr ) / nb_jobs; - int slice_end = FFMIN(((height * (jobnr+1)) / nb_jobs), frame->height); + int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + int slice_end = FFMIN((ff_slice_pos(height, jobnr + 1, nb_jobs)), frame->height); for (plane = 1; plane < 3; plane++) { for (i = slice_start; i < slice_end; i++) { @@ -355,8 +355,8 @@ static int filter_slice_chroma16(AVFilterContext *ctx, void *arg, int jobnr, const int height= AV_CEIL_RSHIFT(frame->height, s->vsub); const int mid = 1 << (s->depth - 1); const int add = ((mid << 1) + 1) << 15; - int slice_start = (height * jobnr ) / nb_jobs; - int slice_end = FFMIN(((height * (jobnr+1)) / nb_jobs), frame->height); + int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + int slice_end = FFMIN((ff_slice_pos(height, jobnr + 1, nb_jobs)), frame->height); for (plane = 1; plane < 3; plane++) { for (i = slice_start; i < slice_end; i++) { @@ -377,8 +377,8 @@ static int filter_slice_alpha(AVFilterContext *ctx, void *arg, int jobnr, FadeContext *s = ctx->priv; AVFrame *frame = arg; int plane = s->is_packed_rgb ? 0 : A; - int slice_start = (frame->height * jobnr ) / nb_jobs; - int slice_end = (frame->height * (jobnr+1)) / nb_jobs; + int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); + int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); int i, j; for (i = slice_start; i < slice_end; i++) { @@ -402,8 +402,8 @@ static int filter_slice_alpha16(AVFilterContext *ctx, void *arg, int jobnr, FadeContext *s = ctx->priv; AVFrame *frame = arg; int plane = s->is_packed_rgb ? 0 : A; - int slice_start = (frame->height * jobnr ) / nb_jobs; - int slice_end = (frame->height * (jobnr+1)) / nb_jobs; + int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); + int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); int i, j; for (i = slice_start; i < slice_end; i++) { diff --git a/libavfilter/vf_fftdnoiz.c b/libavfilter/vf_fftdnoiz.c index 13afbf037..66a889776 100644 --- a/libavfilter/vf_fftdnoiz.c +++ b/libavfilter/vf_fftdnoiz.c @@ -549,8 +549,8 @@ static int denoise(AVFilterContext *ctx, void *arg, PlaneContext *p = &s->planes[plane]; const int nox = p->nox; const int noy = p->noy; - const int slice_start = (noy * jobnr) / nb_jobs; - const int slice_end = (noy * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(noy, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(noy, jobnr + 1, nb_jobs); if (!((1 << plane) & s->planesf) || ctx->is_disabled) continue; diff --git a/libavfilter/vf_fftfilt.c b/libavfilter/vf_fftfilt.c index b94008fc1..043479b0c 100644 --- a/libavfilter/vf_fftfilt.c +++ b/libavfilter/vf_fftfilt.c @@ -133,8 +133,8 @@ static int rdft_horizontal8(AVFilterContext *ctx, void *arg, int jobnr, int nb_j for (int plane = 0; plane < s->nb_planes; plane++) { const int w = s->planewidth[plane]; const int h = s->planeheight[plane]; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); for (int i = slice_start; i < slice_end; i++) { const uint8_t *src = in->data[plane] + i * in->linesize[plane]; @@ -164,8 +164,8 @@ static int rdft_horizontal16(AVFilterContext *ctx, void *arg, int jobnr, int nb_ for (int plane = 0; plane < s->nb_planes; plane++) { const int w = s->planewidth[plane]; const int h = s->planeheight[plane]; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); for (int i = slice_start; i < slice_end; i++) { const uint16_t *src = (const uint16_t *)(in->data[plane] + i * in->linesize[plane]); @@ -195,8 +195,8 @@ static int irdft_horizontal8(AVFilterContext *ctx, void *arg, int jobnr, int nb_ for (int plane = 0; plane < s->nb_planes; plane++) { const int w = s->planewidth[plane]; const int h = s->planeheight[plane]; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); for (int i = slice_start; i < slice_end; i++) s->ihtx_fn(s->ihrdft[jobnr][plane], @@ -226,8 +226,8 @@ static int irdft_horizontal16(AVFilterContext *ctx, void *arg, int jobnr, int nb int max = (1 << s->depth) - 1; const int w = s->planewidth[plane]; const int h = s->planeheight[plane]; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); for (int i = slice_start; i < slice_end; i++) s->ihtx_fn(s->ihrdft[jobnr][plane], @@ -396,8 +396,8 @@ static int multiply_data(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs for (int plane = 0; plane < s->nb_planes; plane++) { const int height = s->rdft_hlen[plane]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); /*Change user defined parameters*/ for (int i = slice_start; i < slice_end; i++) { const double *weight = s->weight[plane] + i * s->rdft_vlen[plane]; @@ -420,8 +420,8 @@ static int copy_vertical(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs const int vlen = s->rdft_vlen[plane]; const int hstride = s->rdft_hstride[plane]; const int vstride = s->rdft_vstride[plane]; - const int slice_start = (hlen * jobnr) / nb_jobs; - const int slice_end = (hlen * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(hlen, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(hlen, jobnr + 1, nb_jobs); const int h = s->planeheight[plane]; float *hdata = s->rdft_hdata_out[plane]; float *vdata = s->rdft_vdata_in[plane]; @@ -442,8 +442,8 @@ static int rdft_vertical(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs for (int plane = 0; plane < s->nb_planes; plane++) { const int height = s->rdft_hlen[plane]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); for (int i = slice_start; i < slice_end; i++) s->vtx_fn(s->vrdft[jobnr][plane], @@ -461,8 +461,8 @@ static int irdft_vertical(AVFilterContext *ctx, void *arg, int jobnr, int nb_job for (int plane = 0; plane < s->nb_planes; plane++) { const int height = s->rdft_hlen[plane]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); for (int i = slice_start; i < slice_end; i++) s->ivtx_fn(s->ivrdft[jobnr][plane], @@ -482,8 +482,8 @@ static int copy_horizontal(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo const int hlen = s->rdft_hlen[plane]; const int hstride = s->rdft_hstride[plane]; const int vstride = s->rdft_vstride[plane]; - const int slice_start = (hlen * jobnr) / nb_jobs; - const int slice_end = (hlen * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(hlen, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(hlen, jobnr + 1, nb_jobs); const int h = s->planeheight[plane]; float *hdata = s->rdft_hdata_in[plane]; float *vdata = s->rdft_vdata_in[plane]; diff --git a/libavfilter/vf_gblur.c b/libavfilter/vf_gblur.c index 0b3756266..45320333f 100644 --- a/libavfilter/vf_gblur.c +++ b/libavfilter/vf_gblur.c @@ -61,8 +61,8 @@ static int filter_horizontally(AVFilterContext *ctx, void *arg, int jobnr, int n ThreadData *td = arg; const int height = td->height; const int width = td->width; - const int slice_start = (height * jobnr ) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const float boundaryscale = s->boundaryscale; const int steps = s->steps; const float nu = s->nu; @@ -83,8 +83,8 @@ static int filter_vertically(AVFilterContext *ctx, void *arg, int jobnr, int nb_ ThreadData *td = arg; const int height = td->height; const int width = td->width; - const int slice_start = (width * jobnr ) / nb_jobs; - const int slice_end = (width * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(width, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(width, jobnr + 1, nb_jobs); const float boundaryscale = s->boundaryscaleV; const int steps = s->steps; const float nu = s->nuV; @@ -105,8 +105,8 @@ static int filter_postscale(AVFilterContext *ctx, void *arg, int jobnr, int nb_j const int height = td->height; const int width = td->width; const int awidth = FFALIGN(width, 64); - const int slice_start = (height * jobnr ) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const float postscale = s->postscale * s->postscaleV; const int slice_size = slice_end - slice_start; diff --git a/libavfilter/vf_geq.c b/libavfilter/vf_geq.c index 13b006595..1256bbe97 100644 --- a/libavfilter/vf_geq.c +++ b/libavfilter/vf_geq.c @@ -405,8 +405,8 @@ static int slice_geq_filter(AVFilterContext *ctx, void *arg, int jobnr, int nb_j const int width = td->width; const int plane = td->plane; const int linesize = td->linesize; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); int x, y; double values[VAR_VARS_NB]; diff --git a/libavfilter/vf_grayworld.c b/libavfilter/vf_grayworld.c index 21d6aafd9..c1821eb7b 100644 --- a/libavfilter/vf_grayworld.c +++ b/libavfilter/vf_grayworld.c @@ -126,8 +126,8 @@ static int convert_frame(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs AVFrame *in = td->in; AVFrame *out = td->out; AVFilterLink *outlink = ctx->outputs[0]; - const int slice_start = (out->height * jobnr) / nb_jobs; - const int slice_end = (out->height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(out->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(out->height, jobnr + 1, nb_jobs); float rgb[3], lab[3]; for (int i = slice_start; i < slice_end; i++) { @@ -193,8 +193,8 @@ static int correct_frame(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs ThreadData *td = arg; AVFrame *out = td->out; AVFilterLink *outlink = ctx->outputs[0]; - const int slice_start = (out->height * jobnr) / nb_jobs; - const int slice_end = (out->height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(out->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(out->height, jobnr + 1, nb_jobs); float rgb[3], lab[3]; for (int i = slice_start; i < slice_end; i++) { diff --git a/libavfilter/vf_guided.c b/libavfilter/vf_guided.c index 4749beab4..005b2128f 100644 --- a/libavfilter/vf_guided.c +++ b/libavfilter/vf_guided.c @@ -113,8 +113,8 @@ static int box_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const int height = t->height; const int src_stride = t->srcStride; const int dst_stride = t->dstStride; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const int radius = s->radius; const float *src = t->src; float *dst = t->dst; diff --git a/libavfilter/vf_hqx.c b/libavfilter/vf_hqx.c index 4dcd03514..370dbc0d7 100644 --- a/libavfilter/vf_hqx.c +++ b/libavfilter/vf_hqx.c @@ -388,8 +388,8 @@ static av_always_inline void hqx_filter(const ThreadData *td, int jobnr, int nb_ const uint32_t *r2y = td->rgbtoyuv; const int height = in->height; const int width = in->width; - const int slice_start = (height * jobnr ) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const int dst_linesize = out->linesize[0]; const int src_linesize = in->linesize[0]; uint8_t *dst = out->data[0] + slice_start * dst_linesize * n; diff --git a/libavfilter/vf_hsvkey.c b/libavfilter/vf_hsvkey.c index 9a1a897a9..804bd8ae0 100644 --- a/libavfilter/vf_hsvkey.c +++ b/libavfilter/vf_hsvkey.c @@ -88,8 +88,8 @@ static int do_hsvkey_slice(AVFilterContext *avctx, void *arg, int jobnr, int nb_ { HSVKeyContext *s = avctx->priv; AVFrame *frame = arg; - const int slice_start = (frame->height * jobnr) / nb_jobs; - const int slice_end = (frame->height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); const int hsub_log2 = s->hsub_log2; const int vsub_log2 = s->vsub_log2; const float hue = s->hue; @@ -113,8 +113,8 @@ static int do_hsvkey16_slice(AVFilterContext *avctx, void *arg, int jobnr, int n { HSVKeyContext *s = avctx->priv; AVFrame *frame = arg; - const int slice_start = (frame->height * jobnr) / nb_jobs; - const int slice_end = (frame->height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); const int hsub_log2 = s->hsub_log2; const int vsub_log2 = s->vsub_log2; const float hue = s->hue; @@ -143,8 +143,8 @@ static int do_hsvhold_slice(AVFilterContext *avctx, void *arg, int jobnr, int nb const int vsub_log2 = s->vsub_log2; const int width = frame->width >> hsub_log2; const int height = frame->height >> vsub_log2; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const float scale = s->scale; const float hue = s->hue; const float sat = s->sat; @@ -179,8 +179,8 @@ static int do_hsvhold16_slice(AVFilterContext *avctx, void *arg, int jobnr, int const int vsub_log2 = s->vsub_log2; const int width = frame->width >> hsub_log2; const int height = frame->height >> vsub_log2; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const float scale = s->scale; const float half = s->half; const float hue = s->hue; diff --git a/libavfilter/vf_huesaturation.c b/libavfilter/vf_huesaturation.c index 7e1b4d1e9..6a4aadeee 100644 --- a/libavfilter/vf_huesaturation.c +++ b/libavfilter/vf_huesaturation.c @@ -103,8 +103,8 @@ static int do_slice_##name##_##xall(AVFilterContext *ctx, \ const int step = s->step; \ const int width = frame->width; \ const int process_h = frame->height; \ - const int slice_start = (process_h * jobnr ) / nb_jobs; \ - const int slice_end = (process_h * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(process_h, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(process_h, jobnr + 1, nb_jobs); \ const ptrdiff_t linesize = frame->linesize[0] / sizeof(type); \ type *row = (type *)frame->data[0] + linesize * slice_start; \ const uint8_t offset_r = s->rgba_map[R]; \ diff --git a/libavfilter/vf_identity.c b/libavfilter/vf_identity.c index 6a94a9235..2e6c06ea7 100644 --- a/libavfilter/vf_identity.c +++ b/libavfilter/vf_identity.c @@ -103,8 +103,8 @@ int compute_images_msad(AVFilterContext *ctx, void *arg, for (int c = 0; c < td->nb_components; c++) { const int outw = td->planewidth[c]; const int outh = td->planeheight[c]; - const int slice_start = (outh * jobnr) / nb_jobs; - const int slice_end = (outh * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(outh, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(outh, jobnr + 1, nb_jobs); const int ref_linesize = td->ref_linesize[c]; const int main_linesize = td->main_linesize[c]; const uint8_t *main_line = td->main_data[c] + main_linesize * slice_start; @@ -131,8 +131,8 @@ int compute_images_identity(AVFilterContext *ctx, void *arg, for (int c = 0; c < td->nb_components; c++) { const int outw = td->planewidth[c]; const int outh = td->planeheight[c]; - const int slice_start = (outh * jobnr) / nb_jobs; - const int slice_end = (outh * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(outh, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(outh, jobnr + 1, nb_jobs); const int ref_linesize = td->ref_linesize[c]; const int main_linesize = td->main_linesize[c]; const uint8_t *main_line = td->main_data[c] + main_linesize * slice_start; diff --git a/libavfilter/vf_lagfun.c b/libavfilter/vf_lagfun.c index 9ec936212..1fdb1b66b 100644 --- a/libavfilter/vf_lagfun.c +++ b/libavfilter/vf_lagfun.c @@ -81,8 +81,8 @@ static int lagfun_frame##name(AVFilterContext *ctx, void *arg, \ AVFrame *out = td->out; \ \ for (int p = 0; p < s->nb_planes; p++) { \ - const int slice_start = (s->planeheight[p] * jobnr) / nb_jobs; \ - const int slice_end = (s->planeheight[p] * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(s->planeheight[p], jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(s->planeheight[p], jobnr + 1, nb_jobs); \ const int width = s->planewidth[p]; \ const type *src = (const type *)in->data[p] + \ slice_start * in->linesize[p] / sizeof(type); \ diff --git a/libavfilter/vf_lensfun.c b/libavfilter/vf_lensfun.c index 668c68562..3b7403c26 100644 --- a/libavfilter/vf_lensfun.c +++ b/libavfilter/vf_lensfun.c @@ -284,8 +284,8 @@ static int config_props(AVFilterLink *inlink) static int vignetting_filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { const VignettingThreadData *thread_data = arg; - const int slice_start = thread_data->height * jobnr / nb_jobs; - const int slice_end = thread_data->height * (jobnr + 1) / nb_jobs; + const int slice_start = ff_slice_pos(thread_data->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(thread_data->height, jobnr + 1, nb_jobs); lf_modifier_apply_color_modification(thread_data->modifier, thread_data->data_in + slice_start * thread_data->linesize_in, @@ -307,8 +307,8 @@ static float square(float x) static int distortion_correction_filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { const DistortionCorrectionThreadData *thread_data = arg; - const int slice_start = thread_data->height * jobnr / nb_jobs; - const int slice_end = thread_data->height * (jobnr + 1) / nb_jobs; + const int slice_start = ff_slice_pos(thread_data->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(thread_data->height, jobnr + 1, nb_jobs); int x, y, i, j, rgb_index; float interpolated, new_x, new_y, d, norm; diff --git a/libavfilter/vf_limitdiff.c b/libavfilter/vf_limitdiff.c index d82327552..fe24df9cc 100644 --- a/libavfilter/vf_limitdiff.c +++ b/libavfilter/vf_limitdiff.c @@ -170,8 +170,8 @@ static int limitdiff_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo const int thr2 = s->thr2; const int w = s->planewidth[p]; const int h = s->planeheight[p]; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const uint8_t *filtered = td->filtered->data[p] + slice_start * filtered_linesize; const uint8_t *source = td->source->data[p] + slice_start * source_linesize; const uint8_t *reference = td->reference->data[p] + slice_start * reference_linesize; diff --git a/libavfilter/vf_limiter.c b/libavfilter/vf_limiter.c index 4f50ace38..68e7e9d98 100644 --- a/libavfilter/vf_limiter.c +++ b/libavfilter/vf_limiter.c @@ -157,8 +157,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) for (p = 0; p < s->nb_planes; p++) { const int h = s->height[p]; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); if (!((1 << p) & s->planes)) { if (out != in) diff --git a/libavfilter/vf_lumakey.c b/libavfilter/vf_lumakey.c index a827d31b4..6e13fbc60 100644 --- a/libavfilter/vf_lumakey.c +++ b/libavfilter/vf_lumakey.c @@ -43,8 +43,8 @@ static int do_lumakey_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_ { LumakeyContext *s = ctx->priv; AVFrame *frame = arg; - const int slice_start = (frame->height * jobnr) / nb_jobs; - const int slice_end = (frame->height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); uint8_t *alpha = frame->data[3] + slice_start * frame->linesize[3]; const uint8_t *luma = frame->data[0] + slice_start * frame->linesize[0]; const int so = s->so; @@ -75,8 +75,8 @@ static int do_lumakey_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb { LumakeyContext *s = ctx->priv; AVFrame *frame = arg; - const int slice_start = (frame->height * jobnr) / nb_jobs; - const int slice_end = (frame->height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs); uint16_t *alpha = (uint16_t *)(frame->data[3] + slice_start * frame->linesize[3]); const uint16_t *luma = (const uint16_t *)(frame->data[0] + slice_start * frame->linesize[0]); const int so = s->so; diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c index 14c996475..8d6c2907d 100644 --- a/libavfilter/vf_lut.c +++ b/libavfilter/vf_lut.c @@ -358,8 +358,8 @@ struct thread_data { const uint16_t (*tab)[256*256] = (const uint16_t (*)[256*256])s->lut;\ const int step = s->step;\ \ - const int slice_start = (h * jobnr ) / nb_jobs;\ - const int slice_end = (h * (jobnr+1)) / nb_jobs;\ + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); \ /* packed, 16-bit */ static int lut_packed_16bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) @@ -441,8 +441,8 @@ static int lut_packed_8bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_j int w = AV_CEIL_RSHIFT(td->w, hsub);\ const uint16_t *tab = s->lut[plane];\ \ - const int slice_start = (h * jobnr ) / nb_jobs;\ - const int slice_end = (h * (jobnr+1)) / nb_jobs;\ + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); \ /* planar >8 bit depth */ static int lut_planar_16bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) diff --git a/libavfilter/vf_lut2.c b/libavfilter/vf_lut2.c index 3b8ee3af6..cabdc980e 100644 --- a/libavfilter/vf_lut2.c +++ b/libavfilter/vf_lut2.c @@ -259,8 +259,8 @@ static int lut2_##zname##_##xname##_##yname(AVFilterContext *ctx, int p, y, x; \ \ for (p = 0; p < s->nb_planes; p++) { \ - const int slice_start = (s->heightx[p] * jobnr) / nb_jobs; \ - const int slice_end = (s->heightx[p] * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(s->heightx[p], jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(s->heightx[p], jobnr + 1, nb_jobs); \ const uint16_t *lut = s->lut[p]; \ const xtype *srcxx; \ const ytype *srcyy; \ diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c index 4ed609d81..6ab33790c 100644 --- a/libavfilter/vf_lut3d.c +++ b/libavfilter/vf_lut3d.c @@ -328,8 +328,8 @@ static int interp_##nbits##_##name##_p##depth(AVFilterContext *ctx, void *arg, i const AVFrame *in = td->in; \ const AVFrame *out = td->out; \ const int direct = out == in; \ - const int slice_start = (in->height * jobnr ) / nb_jobs; \ - const int slice_end = (in->height * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(in->height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(in->height, jobnr + 1, nb_jobs); \ uint8_t *grow = out->data[0] + slice_start * out->linesize[0]; \ uint8_t *brow = out->data[1] + slice_start * out->linesize[1]; \ uint8_t *rrow = out->data[2] + slice_start * out->linesize[2]; \ @@ -426,8 +426,8 @@ static int interp_##name##_pf##depth(AVFilterContext *ctx, void *arg, int jobnr, const AVFrame *in = td->in; \ const AVFrame *out = td->out; \ const int direct = out == in; \ - const int slice_start = (in->height * jobnr ) / nb_jobs; \ - const int slice_end = (in->height * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(in->height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(in->height, jobnr + 1, nb_jobs); \ uint8_t *grow = out->data[0] + slice_start * out->linesize[0]; \ uint8_t *brow = out->data[1] + slice_start * out->linesize[1]; \ uint8_t *rrow = out->data[2] + slice_start * out->linesize[2]; \ @@ -498,8 +498,8 @@ static int interp_##nbits##_##name(AVFilterContext *ctx, void *arg, int jobnr, i const uint8_t g = lut3d->rgba_map[G]; \ const uint8_t b = lut3d->rgba_map[B]; \ const uint8_t a = lut3d->rgba_map[A]; \ - const int slice_start = (in->height * jobnr ) / nb_jobs; \ - const int slice_end = (in->height * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(in->height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(in->height, jobnr + 1, nb_jobs); \ uint8_t *dstrow = out->data[0] + slice_start * out->linesize[0]; \ const uint8_t *srcrow = in ->data[0] + slice_start * in ->linesize[0]; \ const float lut_max = lut3d->lutsize - 1; \ @@ -1870,8 +1870,8 @@ static int interp_1d_##nbits##_##name##_p##depth(AVFilterContext *ctx, \ const AVFrame *in = td->in; \ const AVFrame *out = td->out; \ const int direct = out == in; \ - const int slice_start = (in->height * jobnr ) / nb_jobs; \ - const int slice_end = (in->height * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(in->height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(in->height, jobnr + 1, nb_jobs); \ uint8_t *grow = out->data[0] + slice_start * out->linesize[0]; \ uint8_t *brow = out->data[1] + slice_start * out->linesize[1]; \ uint8_t *rrow = out->data[2] + slice_start * out->linesize[2]; \ @@ -1966,8 +1966,8 @@ static int interp_1d_##name##_pf##depth(AVFilterContext *ctx, \ const AVFrame *in = td->in; \ const AVFrame *out = td->out; \ const int direct = out == in; \ - const int slice_start = (in->height * jobnr ) / nb_jobs; \ - const int slice_end = (in->height * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(in->height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(in->height, jobnr + 1, nb_jobs); \ uint8_t *grow = out->data[0] + slice_start * out->linesize[0]; \ uint8_t *brow = out->data[1] + slice_start * out->linesize[1]; \ uint8_t *rrow = out->data[2] + slice_start * out->linesize[2]; \ @@ -2036,8 +2036,8 @@ static int interp_1d_##nbits##_##name(AVFilterContext *ctx, void *arg, \ const uint8_t g = lut1d->rgba_map[G]; \ const uint8_t b = lut1d->rgba_map[B]; \ const uint8_t a = lut1d->rgba_map[A]; \ - const int slice_start = (in->height * jobnr ) / nb_jobs; \ - const int slice_end = (in->height * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(in->height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(in->height, jobnr + 1, nb_jobs); \ uint8_t *dstrow = out->data[0] + slice_start * out->linesize[0]; \ const uint8_t *srcrow = in ->data[0] + slice_start * in ->linesize[0]; \ const float factor = (1 << nbits) - 1; \ diff --git a/libavfilter/vf_maskedclamp.c b/libavfilter/vf_maskedclamp.c index 606afd391..f287c136a 100644 --- a/libavfilter/vf_maskedclamp.c +++ b/libavfilter/vf_maskedclamp.c @@ -94,8 +94,8 @@ static int maskedclamp_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_ const ptrdiff_t dlinesize = td->d->linesize[p]; const int w = s->width[p]; const int h = s->height[p]; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const uint8_t *bsrc = td->b->data[p] + slice_start * blinesize; const uint8_t *darksrc = td->o->data[p] + slice_start * darklinesize; const uint8_t *brightsrc = td->m->data[p] + slice_start * brightlinesize; diff --git a/libavfilter/vf_maskedmerge.c b/libavfilter/vf_maskedmerge.c index 18b960034..299c05c1b 100644 --- a/libavfilter/vf_maskedmerge.c +++ b/libavfilter/vf_maskedmerge.c @@ -76,8 +76,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) for (p = 0; p < s->nb_planes; p++) { const int h = s->height[p]; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); if (!((1 << p) & s->planes)) { av_image_copy_plane(out->data[p] + slice_start * out->linesize[p], diff --git a/libavfilter/vf_maskedminmax.c b/libavfilter/vf_maskedminmax.c index b6762e16b..5e630711e 100644 --- a/libavfilter/vf_maskedminmax.c +++ b/libavfilter/vf_maskedminmax.c @@ -149,8 +149,8 @@ static int maskedminmax_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb const ptrdiff_t dst_linesize = td->dst->linesize[p]; const int w = s->planewidth[p]; const int h = s->planeheight[p]; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const uint8_t *src = td->src->data[p] + slice_start * src_linesize; const uint8_t *f1 = td->f1->data[p] + slice_start * f1_linesize; const uint8_t *f2 = td->f2->data[p] + slice_start * f2_linesize; diff --git a/libavfilter/vf_maskedthreshold.c b/libavfilter/vf_maskedthreshold.c index 41c204f6f..649b9558d 100644 --- a/libavfilter/vf_maskedthreshold.c +++ b/libavfilter/vf_maskedthreshold.c @@ -154,8 +154,8 @@ static int threshold_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo const ptrdiff_t dst_linesize = td->dst->linesize[p]; const int w = s->planewidth[p]; const int h = s->planeheight[p]; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const uint8_t *src = td->src->data[p] + slice_start * src_linesize; const uint8_t *ref = td->ref->data[p] + slice_start * ref_linesize; uint8_t *dst = td->dst->data[p] + slice_start * dst_linesize; diff --git a/libavfilter/vf_maskfun.c b/libavfilter/vf_maskfun.c index 9869ae4e3..f04fb40ae 100644 --- a/libavfilter/vf_maskfun.c +++ b/libavfilter/vf_maskfun.c @@ -168,8 +168,8 @@ static int maskfun##name(AVFilterContext *ctx, void *arg, \ const int linesize = out->linesize[p] / div; \ const int w = s->planewidth[p]; \ const int h = s->planeheight[p]; \ - const int slice_start = (h * jobnr) / nb_jobs; \ - const int slice_end = (h * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); \ const type *src = (type *)in->data[p] + \ slice_start * src_linesize; \ type *dst = (type *)out->data[p] + \ diff --git a/libavfilter/vf_median.c b/libavfilter/vf_median.c index 6e00cdf88..3b11adbca 100644 --- a/libavfilter/vf_median.c +++ b/libavfilter/vf_median.c @@ -186,8 +186,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) for (int plane = 0; plane < s->nb_planes; plane++) { const int h = s->planeheight[plane]; const int w = s->planewidth[plane]; - const int slice_h_start = (h * jobnr) / nb_jobs; - const int slice_h_end = (h * (jobnr+1)) / nb_jobs; + const int slice_h_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_h_end = ff_slice_pos(h, jobnr + 1, nb_jobs); if (!(s->planes & (1 << plane))) { av_image_copy_plane(out->data[plane] + slice_h_start * out->linesize[plane], diff --git a/libavfilter/vf_mix.c b/libavfilter/vf_mix.c index 517bb2450..3143f6e9c 100644 --- a/libavfilter/vf_mix.c +++ b/libavfilter/vf_mix.c @@ -159,8 +159,8 @@ typedef struct ThreadData { #define FAST_TMIX_SLICE(type, stype, round) \ for (int p = 0; p < s->nb_planes; p++) { \ - const int slice_start = (s->height[p] * jobnr) / nb_jobs; \ - const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(s->height[p], jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(s->height[p], jobnr + 1, nb_jobs); \ const int width = s->linesizes[p] / sizeof(type); \ stype *sum = (stype *)(s->sum[p] + slice_start * s->linesizes[p] * 2); \ type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ @@ -198,8 +198,8 @@ typedef struct ThreadData { #define MIX_SLICE(type, fun, clip) \ for (int p = 0; p < s->nb_planes; p++) { \ - const int slice_start = (s->height[p] * jobnr) / nb_jobs; \ - const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(s->height[p], jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(s->height[p], jobnr + 1, nb_jobs); \ const int width = s->linesizes[p] / sizeof(type); \ type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ const ptrdiff_t dst_linesize = out->linesize[p] / sizeof(type); \ diff --git a/libavfilter/vf_monochrome.c b/libavfilter/vf_monochrome.c index 471864292..1e6d6539c 100644 --- a/libavfilter/vf_monochrome.c +++ b/libavfilter/vf_monochrome.c @@ -87,8 +87,8 @@ static int monochrome_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_ const float imax = 1.f / max; const int width = frame->width; const int height = frame->height; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t ylinesize = frame->linesize[0]; const ptrdiff_t ulinesize = frame->linesize[1]; const ptrdiff_t vlinesize = frame->linesize[2]; @@ -126,8 +126,8 @@ static int monochrome_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb const float imax = 1.f / max; const int width = frame->width; const int height = frame->height; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t ylinesize = frame->linesize[0] / 2; const ptrdiff_t ulinesize = frame->linesize[1] / 2; const ptrdiff_t vlinesize = frame->linesize[2] / 2; @@ -164,8 +164,8 @@ static int clear_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const int subh = s->subh; const int width = AV_CEIL_RSHIFT(frame->width, subw); const int height = AV_CEIL_RSHIFT(frame->height, subh); - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t ulinesize = frame->linesize[1]; const ptrdiff_t vlinesize = frame->linesize[2]; @@ -190,8 +190,8 @@ static int clear_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs const int subh = s->subh; const int width = AV_CEIL_RSHIFT(frame->width, subw); const int height = AV_CEIL_RSHIFT(frame->height, subh); - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t ulinesize = frame->linesize[1] / 2; const ptrdiff_t vlinesize = frame->linesize[2] / 2; diff --git a/libavfilter/vf_morpho.c b/libavfilter/vf_morpho.c index 098d00dfd..342ead266 100644 --- a/libavfilter/vf_morpho.c +++ b/libavfilter/vf_morpho.c @@ -802,8 +802,8 @@ static int morpho_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) for (int p = 0; p < s->nb_planes; p++) { const int width = s->planewidth[p]; const int height = s->planeheight[p]; - const int y0 = (height * jobnr ) / nb_jobs; - const int y1 = (height * (jobnr+1)) / nb_jobs; + const int y0 = ff_slice_pos(height, jobnr, nb_jobs); + const int y1 = ff_slice_pos(height, jobnr + 1, nb_jobs); const int depth = s->depth; if (ctx->is_disabled || !(s->planes & (1 << p))) { @@ -857,8 +857,8 @@ static int morpho_sliceX(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs for (int p = 0; p < s->nb_planes; p++) { const int height = s->planeheight[p]; - const int y0 = (height * jobnr ) / nb_jobs; - const int y1 = (height * (jobnr+1)) / nb_jobs; + const int y0 = ff_slice_pos(height, jobnr, nb_jobs); + const int y1 = ff_slice_pos(height, jobnr + 1, nb_jobs); if (ctx->is_disabled || !(s->planes & (1 << p))) { copy: diff --git a/libavfilter/vf_multiply.c b/libavfilter/vf_multiply.c index f7db2195d..da3104f71 100644 --- a/libavfilter/vf_multiply.c +++ b/libavfilter/vf_multiply.c @@ -98,8 +98,8 @@ static int multiply_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_job const ptrdiff_t dst_linesize = td->dst->linesize[p]; const int w = td->src->width; const int h = td->src->height; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const uint8_t *src = td->src->data[p] + slice_start * src_linesize; const uint8_t *ref = td->ref->data[p] + slice_start * ref_linesize; uint8_t *dst = td->dst->data[p] + slice_start * dst_linesize; diff --git a/libavfilter/vf_negate.c b/libavfilter/vf_negate.c index f61f7ebbb..bc05cb840 100644 --- a/libavfilter/vf_negate.c +++ b/libavfilter/vf_negate.c @@ -277,8 +277,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) for (int p = 0; p < s->nb_planes; p++) { const int h = s->height[p]; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); if (!((1 << p) & s->planes)) { if (out != in) diff --git a/libavfilter/vf_neighbor.c b/libavfilter/vf_neighbor.c index 7bdc2ab91..b121a4856 100644 --- a/libavfilter/vf_neighbor.c +++ b/libavfilter/vf_neighbor.c @@ -268,8 +268,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const int dstride = out->linesize[plane]; const int height = s->planeheight[plane]; const int width = s->planewidth[plane]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const uint8_t *src = (const uint8_t *)in->data[plane] + slice_start * stride; uint8_t *dst = out->data[plane] + slice_start * dstride; diff --git a/libavfilter/vf_nlmeans.c b/libavfilter/vf_nlmeans.c index 2679e5fee..35ff499d5 100644 --- a/libavfilter/vf_nlmeans.c +++ b/libavfilter/vf_nlmeans.c @@ -292,8 +292,8 @@ static int nlmeans_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs const struct thread_data *td = arg; const ptrdiff_t src_linesize = td->src_linesize; const int process_h = td->endy - td->starty; - const int slice_start = (process_h * jobnr ) / nb_jobs; - const int slice_end = (process_h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(process_h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(process_h, jobnr + 1, nb_jobs); const int starty = td->starty + slice_start; const int endy = td->starty + slice_end; const int p = td->p; diff --git a/libavfilter/vf_nnedi.c b/libavfilter/vf_nnedi.c index d3f52b3f9..148791f80 100644 --- a/libavfilter/vf_nnedi.c +++ b/libavfilter/vf_nnedi.c @@ -551,8 +551,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) for (int p = 0; p < s->nb_planes; p++) { const int height = s->planeheight[p]; const int width = s->planewidth[p]; - const int slice_start = 2 * ((height / 2 * jobnr) / nb_jobs); - const int slice_end = 2 * ((height / 2 * (jobnr+1)) / nb_jobs); + const int slice_start = 2 * (ff_slice_pos(height / 2, jobnr, nb_jobs)); + const int slice_end = 2 * (ff_slice_pos(height / 2, jobnr + 1, nb_jobs)); const uint8_t *src_data = in->data[p]; uint8_t *dst_data = out->data[p]; uint8_t *dst = out->data[p] + slice_start * out->linesize[p]; diff --git a/libavfilter/vf_noise.c b/libavfilter/vf_noise.c index ae4a08ca5..2760e4b0e 100644 --- a/libavfilter/vf_noise.c +++ b/libavfilter/vf_noise.c @@ -231,8 +231,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) for (plane = 0; plane < s->nb_planes; plane++) { const int height = s->height[plane]; - const int start = (height * jobnr ) / nb_jobs; - const int end = (height * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(height, jobnr, nb_jobs); + const int end = ff_slice_pos(height, jobnr + 1, nb_jobs); noise(td->out->data[plane] + start * td->out->linesize[plane], td->in->data[plane] + start * td->in->linesize[plane], td->out->linesize[plane], td->in->linesize[plane], diff --git a/libavfilter/vf_opencolorio.c b/libavfilter/vf_opencolorio.c index d34922dec..80bcfa133 100644 --- a/libavfilter/vf_opencolorio.c +++ b/libavfilter/vf_opencolorio.c @@ -19,6 +19,7 @@ */ #include "avfilter.h" +#include "filters.h" #include "formats.h" #include "libavutil/half2float.h" #include "libavutil/opt.h" @@ -55,8 +56,8 @@ static int ocio_filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_ AVFrame *in = td->in; AVFrame *out = td->out; const int height = out->height; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const int slice_h = slice_end - slice_start; return ocio_apply(ctx, s->ocio, in, out, slice_start, slice_h); diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index d627db088..43f6e736c 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -397,8 +397,8 @@ static av_always_inline void blend_slice_packed_rgb(AVFilterContext *ctx, i = FFMAX(-y, 0); imax = FFMIN3(-y + dst_h, FFMIN(src_h, dst_h), y + src_h); - slice_start = i + (imax * jobnr) / nb_jobs; - slice_end = i + (imax * (jobnr+1)) / nb_jobs; + slice_start = i + ff_slice_pos(imax, jobnr, nb_jobs); + slice_end = i + ff_slice_pos(imax, jobnr + 1, nb_jobs); sp = src->data[0] + (slice_start) * src->linesize[0]; dp = dst->data[0] + (y + slice_start) * dst->linesize[0]; @@ -484,8 +484,8 @@ static av_always_inline void blend_plane_##depth##_##nbits##bits(AVFilterContext \ const int jmin = FFMAX(-yp, 0), jmax = FFMIN3(-yp + dst_hp, FFMIN(src_hp, dst_hp), yp + src_hp); \ const int kmin = FFMAX(-xp, 0), kmax = FFMIN(-xp + dst_wp, src_wp); \ - const int slice_start = jmin + (jmax * jobnr) / nb_jobs; \ - const int slice_end = jmin + (jmax * (jobnr + 1)) / nb_jobs; \ + const int slice_start = jmin + ff_slice_pos(jmax, jobnr, nb_jobs); \ + const int slice_end = jmin + ff_slice_pos(jmax, jobnr + 1, nb_jobs); \ \ const uint8_t *sp = src->data[i] + (slice_start) * src->linesize[i]; \ uint8_t *dp = dst->data[dst_plane] \ @@ -594,8 +594,8 @@ static inline void alpha_composite_##depth##_##nbits##bits(const AVFrame *src, c \ const int imin = FFMAX(-y, 0), imax = FFMIN3(-y + dst_h, FFMIN(src_h, dst_h), y + src_h); \ const int jmin = FFMAX(-x, 0), jmax = FFMIN(-x + dst_w, src_w); \ - const int slice_start = imin + ( imax * jobnr) / nb_jobs; \ - const int slice_end = imin + ((imax * (jobnr + 1)) / nb_jobs); \ + const int slice_start = imin + ff_slice_pos(imax, jobnr, nb_jobs); \ + const int slice_end = imin + (ff_slice_pos(imax, jobnr + 1, nb_jobs)); \ \ const uint8_t *sa = src->data[3] + (slice_start) * src->linesize[3]; \ uint8_t *da = dst->data[3] + (y + slice_start) * dst->linesize[3]; \ diff --git a/libavfilter/vf_photosensitivity.c b/libavfilter/vf_photosensitivity.c index b8d3667ff..c14d7b302 100644 --- a/libavfilter/vf_photosensitivity.c +++ b/libavfilter/vf_photosensitivity.c @@ -84,8 +84,8 @@ static int convert_frame_partial(AVFilterContext *ctx, void *arg, int jobnr, int ThreadData_convert_frame *td = arg; - const int slice_start = (NUM_CELLS * jobnr) / nb_jobs; - const int slice_end = (NUM_CELLS * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(NUM_CELLS, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(NUM_CELLS, jobnr + 1, nb_jobs); int width = td->in->width, height = td->in->height, linesize = td->in->linesize[0], skip = td->skip; const uint8_t *data = td->in->data[0]; @@ -149,8 +149,8 @@ static int blend_frame_partial(AVFilterContext *ctx, void *arg, int jobnr, int n ThreadData_blend_frame *td = arg; const uint16_t s_mul = td->s_mul; const uint16_t t_mul = 0x100 - s_mul; - const int slice_start = (td->target->height * jobnr) / nb_jobs; - const int slice_end = (td->target->height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(td->target->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(td->target->height, jobnr + 1, nb_jobs); const int linesize = td->target->linesize[0]; for (y = slice_start; y < slice_end; y++) { diff --git a/libavfilter/vf_pixelize.c b/libavfilter/vf_pixelize.c index a6f0e38dd..abde241d1 100644 --- a/libavfilter/vf_pixelize.c +++ b/libavfilter/vf_pixelize.c @@ -189,10 +189,10 @@ static int pixelize_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_job const int wh = s->planeheight[p]; const int h = (s->planeheight[p] + s->block_h[p] - 1) / s->block_h[p]; const int w = (s->planewidth[p] + s->block_w[p] - 1) / s->block_w[p]; - const int wslice_start = (wh * jobnr) / nb_jobs; - const int wslice_end = (wh * (jobnr+1)) / nb_jobs; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int wslice_start = ff_slice_pos(wh, jobnr, nb_jobs); + const int wslice_end = ff_slice_pos(wh, jobnr + 1, nb_jobs); + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const ptrdiff_t out_linesize = out->linesize[p]; const ptrdiff_t in_linesize = in->linesize[p]; const uint8_t *src = in->data[p]; diff --git a/libavfilter/vf_premultiply.c b/libavfilter/vf_premultiply.c index 93e74d6c9..1cea3cab7 100644 --- a/libavfilter/vf_premultiply.c +++ b/libavfilter/vf_premultiply.c @@ -507,8 +507,8 @@ static int premultiply_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_ int p; for (p = 0; p < s->nb_planes; p++) { - const int slice_start = (s->height[p] * jobnr) / nb_jobs; - const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(s->height[p], jobnr, nb_jobs); + const int slice_end = ff_slice_pos(s->height[p], jobnr + 1, nb_jobs); if (!((1 << p) & s->planes) || p == 3) { av_image_copy_plane(out->data[p] + slice_start * out->linesize[p], diff --git a/libavfilter/vf_pseudocolor.c b/libavfilter/vf_pseudocolor.c index 7d5657f26..793278ce8 100644 --- a/libavfilter/vf_pseudocolor.c +++ b/libavfilter/vf_pseudocolor.c @@ -981,9 +981,9 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) AVFrame *out = td->out; for (int plane = 0; plane < s->nb_planes; plane++) { - const int slice_start = (s->height[plane] * jobnr) / nb_jobs; - const int slice_end = (s->height[plane] * (jobnr+1)) / nb_jobs; - const int islice_start = (s->height[s->index] * jobnr) / nb_jobs; + const int slice_start = ff_slice_pos(s->height[plane], jobnr, nb_jobs); + const int slice_end = ff_slice_pos(s->height[plane], jobnr + 1, nb_jobs); + const int islice_start = ff_slice_pos(s->height[s->index], jobnr, nb_jobs); ptrdiff_t ilinesize = in->linesize[s->index]; ptrdiff_t slinesize = in->linesize[plane]; ptrdiff_t dlinesize = out->linesize[plane]; diff --git a/libavfilter/vf_psnr.c b/libavfilter/vf_psnr.c index 4a173c73d..baaf7605c 100644 --- a/libavfilter/vf_psnr.c +++ b/libavfilter/vf_psnr.c @@ -104,8 +104,8 @@ int compute_images_mse(AVFilterContext *ctx, void *arg, for (int c = 0; c < td->nb_components; c++) { const int outw = td->planewidth[c]; const int outh = td->planeheight[c]; - const int slice_start = (outh * jobnr) / nb_jobs; - const int slice_end = (outh * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(outh, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(outh, jobnr + 1, nb_jobs); const int ref_linesize = td->ref_linesize[c]; const int main_linesize = td->main_linesize[c]; const uint8_t *main_line = td->main_data[c] + main_linesize * slice_start; diff --git a/libavfilter/vf_remap.c b/libavfilter/vf_remap.c index c3f02c4cf..de83bb467 100644 --- a/libavfilter/vf_remap.c +++ b/libavfilter/vf_remap.c @@ -143,8 +143,8 @@ static int remap_planar##bits##_##name##_slice(AVFilterContext *ctx, void *arg, const AVFrame *xin = td->xin; \ const AVFrame *yin = td->yin; \ const AVFrame *out = td->out; \ - const int slice_start = (out->height * jobnr ) / nb_jobs; \ - const int slice_end = (out->height * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(out->height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(out->height, jobnr + 1, nb_jobs); \ const int xlinesize = xin->linesize[0] / 2; \ const int ylinesize = yin->linesize[0] / 2; \ int x , y, plane; \ @@ -194,8 +194,8 @@ static int remap_packed##bits##_##name##_slice(AVFilterContext *ctx, void *arg, const AVFrame *xin = td->xin; \ const AVFrame *yin = td->yin; \ const AVFrame *out = td->out; \ - const int slice_start = (out->height * jobnr ) / nb_jobs; \ - const int slice_end = (out->height * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(out->height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(out->height, jobnr + 1, nb_jobs); \ const int dlinesize = out->linesize[0] / div; \ const int slinesize = in->linesize[0] / div; \ const int xlinesize = xin->linesize[0] / 2; \ diff --git a/libavfilter/vf_removegrain.c b/libavfilter/vf_removegrain.c index 0a0c60fb2..faaa6af71 100644 --- a/libavfilter/vf_removegrain.c +++ b/libavfilter/vf_removegrain.c @@ -523,8 +523,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const int om = in->linesize[i] - 1; const int o0 = in->linesize[i] ; const int op = in->linesize[i] + 1; - int start = (height * jobnr ) / nb_jobs; - int end = (height * (jobnr+1)) / nb_jobs; + int start = ff_slice_pos(height, jobnr, nb_jobs); + int end = ff_slice_pos(height, jobnr + 1, nb_jobs); int x, y; start = FFMAX(1, start); diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index d113298ff..6811c8442 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -658,7 +658,8 @@ static int config_props(AVFilterLink *outlink) if (scale->reset_sar) outlink->sample_aspect_ratio = (AVRational){1, 1}; else if (inlink0->sample_aspect_ratio.num){ - outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink0->w, outlink->w * inlink0->h}, inlink0->sample_aspect_ratio); + AVRational q = av_div_q((AVRational){inlink0->w, inlink0->h}, (AVRational){outlink->w, outlink->h}); + outlink->sample_aspect_ratio = av_mul_q(q, inlink0->sample_aspect_ratio); } else outlink->sample_aspect_ratio = inlink0->sample_aspect_ratio; diff --git a/libavfilter/vf_scroll.c b/libavfilter/vf_scroll.c index cd728a496..d64ac2733 100644 --- a/libavfilter/vf_scroll.c +++ b/libavfilter/vf_scroll.c @@ -80,8 +80,8 @@ static int scroll_slice(AVFilterContext *ctx, void *arg, int jobnr, const uint8_t *src = in->data[p]; const int h = s->planeheight[p]; const int w = s->planewidth[p] * s->bytes; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); uint8_t *dst = out->data[p] + slice_start * out->linesize[p]; for (int y = slice_start; y < slice_end; y++) { diff --git a/libavfilter/vf_selectivecolor.c b/libavfilter/vf_selectivecolor.c index 99aa32f01..4fa8b32f3 100644 --- a/libavfilter/vf_selectivecolor.c +++ b/libavfilter/vf_selectivecolor.c @@ -316,8 +316,8 @@ static inline int selective_color_##nbits(AVFilterContext *ctx, ThreadData *td, const SelectiveColorContext *s = ctx->priv; \ const int height = in->height; \ const int width = in->width; \ - const int slice_start = (height * jobnr ) / nb_jobs; \ - const int slice_end = (height * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); \ const int dst_linesize = out->linesize[0] / ((nbits + 7) / 8); \ const int src_linesize = in->linesize[0] / ((nbits + 7) / 8); \ const uint8_t roffset = s->rgba_map[R]; \ diff --git a/libavfilter/vf_shear.c b/libavfilter/vf_shear.c index 11edd1063..1c24a3647 100644 --- a/libavfilter/vf_shear.c +++ b/libavfilter/vf_shear.c @@ -130,8 +130,8 @@ static int filter_slice_nn##name(AVFilterContext *ctx, void *arg, int jobnr, \ const int height = s->planeheight[p]; \ const int wx = vsub * shx * height * 0.5f / hsub; \ const int wy = hsub * shy * width * 0.5f / vsub; \ - const int slice_start = (height * jobnr) / nb_jobs; \ - const int slice_end = (height * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); \ const int src_linesize = in->linesize[p] / sizeof(type); \ const int dst_linesize = out->linesize[p] / sizeof(type); \ const type *src = (const type *)in->data[p]; \ @@ -177,8 +177,8 @@ static int filter_slice_bl##name(AVFilterContext *ctx, void *arg, int jobnr, \ const int height = s->planeheight[p]; \ const float wx = vsub * shx * height * 0.5f / hsub; \ const float wy = hsub * shy * width * 0.5f / vsub; \ - const int slice_start = (height * jobnr) / nb_jobs; \ - const int slice_end = (height * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); \ const int src_linesize = in->linesize[p] / sizeof(type); \ const int dst_linesize = out->linesize[p] / sizeof(type); \ const type *src = (const type *)in->data[p]; \ diff --git a/libavfilter/vf_shufflepixels.c b/libavfilter/vf_shufflepixels.c index 3ba950f7b..ebe0b8115 100644 --- a/libavfilter/vf_shufflepixels.c +++ b/libavfilter/vf_shufflepixels.c @@ -204,8 +204,8 @@ static int shuffle_horizontal## name(AVFilterContext *ctx, void *arg, \ AVFrame *out = td->out; \ \ for (int p = 0; p < s->nb_planes; p++) { \ - const int slice_start = (s->planeheight[p] * jobnr) / nb_jobs; \ - const int slice_end = (s->planeheight[p] * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(s->planeheight[p], jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(s->planeheight[p], jobnr + 1, nb_jobs); \ type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ const type *src = (const type *)(in->data[p] + \ slice_start * in->linesize[p]); \ @@ -237,8 +237,8 @@ static int shuffle_vertical## name(AVFilterContext *ctx, void *arg, \ AVFrame *out = td->out; \ \ for (int p = 0; p < s->nb_planes; p++) { \ - const int slice_start = (s->planeheight[p] * jobnr) / nb_jobs; \ - const int slice_end = (s->planeheight[p] * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(s->planeheight[p], jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(s->planeheight[p], jobnr + 1, nb_jobs); \ type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ const int32_t *map = s->map; \ \ @@ -267,8 +267,8 @@ static int shuffle_block## name(AVFilterContext *ctx, void *arg, \ AVFrame *out = td->out; \ \ for (int p = 0; p < s->nb_planes; p++) { \ - const int slice_start = (s->planeheight[p] * jobnr) / nb_jobs; \ - const int slice_end = (s->planeheight[p] * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(s->planeheight[p], jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(s->planeheight[p], jobnr + 1, nb_jobs); \ type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ const type *src = (const type *)in->data[p]; \ const int32_t *map = s->map + slice_start * s->planewidth[p]; \ diff --git a/libavfilter/vf_signalstats.c b/libavfilter/vf_signalstats.c index 77b94669b..5859b4647 100644 --- a/libavfilter/vf_signalstats.c +++ b/libavfilter/vf_signalstats.c @@ -218,8 +218,8 @@ static int filter8_brng(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) AVFrame *out = td->out; const int w = in->width; const int h = in->height; - const int slice_start = (h * jobnr ) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); int x, y, score = 0; for (y = slice_start; y < slice_end; y++) { @@ -253,8 +253,8 @@ static int filter16_brng(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs const int mult = 1 << (s->depth - 8); const int w = in->width; const int h = in->height; - const int slice_start = (h * jobnr ) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); int x, y, score = 0; for (y = slice_start; y < slice_end; y++) { @@ -292,8 +292,8 @@ static int filter8_tout(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) AVFrame *out = td->out; const int w = in->width; const int h = in->height; - const int slice_start = (h * jobnr ) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const uint8_t *p = in->data[0]; int lw = in->linesize[0]; int x, y, score = 0, filt; @@ -340,8 +340,8 @@ static int filter16_tout(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs AVFrame *out = td->out; const int w = in->width; const int h = in->height; - const int slice_start = (h * jobnr ) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const uint16_t *p = (uint16_t *)in->data[0]; int lw = in->linesize[0] / 2; int x, y, score = 0, filt; @@ -383,8 +383,8 @@ static int filter8_vrep(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) AVFrame *out = td->out; const int w = in->width; const int h = in->height; - const int slice_start = (h * jobnr ) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const uint8_t *p = in->data[0]; const int lw = in->linesize[0]; int x, y, score = 0; @@ -417,8 +417,8 @@ static int filter16_vrep(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs AVFrame *out = td->out; const int w = in->width; const int h = in->height; - const int slice_start = (h * jobnr ) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const uint16_t *p = (uint16_t *)in->data[0]; const int lw = in->linesize[0] / 2; int x, y, score = 0; @@ -464,8 +464,8 @@ static int compute_sat_hue_metrics8(AVFilterContext *ctx, void *arg, int jobnr, AVFrame *dst_sat = td->dst_sat; AVFrame *dst_hue = td->dst_hue; - const int slice_start = (s->chromah * jobnr ) / nb_jobs; - const int slice_end = (s->chromah * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(s->chromah, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(s->chromah, jobnr + 1, nb_jobs); const int lsz_u = src->linesize[1]; const int lsz_v = src->linesize[2]; @@ -503,8 +503,8 @@ static int compute_sat_hue_metrics16(AVFilterContext *ctx, void *arg, int jobnr, AVFrame *dst_hue = td->dst_hue; const int mid = 1 << (s->depth - 1); - const int slice_start = (s->chromah * jobnr ) / nb_jobs; - const int slice_end = (s->chromah * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(s->chromah, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(s->chromah, jobnr + 1, nb_jobs); const int lsz_u = src->linesize[1] / 2; const int lsz_v = src->linesize[2] / 2; diff --git a/libavfilter/vf_ssim.c b/libavfilter/vf_ssim.c index dfb91e8da..85aa42068 100644 --- a/libavfilter/vf_ssim.c +++ b/libavfilter/vf_ssim.c @@ -247,8 +247,8 @@ static int ssim_plane_16bit(AVFilterContext *ctx, void *arg, const int ref_stride = td->ref_linesize[c]; int width = td->planewidth[c]; int height = td->planeheight[c]; - const int slice_start = ((height >> 2) * jobnr) / nb_jobs; - const int slice_end = ((height >> 2) * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height >> 2, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height >> 2, jobnr + 1, nb_jobs); const int ystart = FFMAX(1, slice_start); int z = ystart - 1; double ssim = 0.0; @@ -290,8 +290,8 @@ static int ssim_plane(AVFilterContext *ctx, void *arg, const int ref_stride = td->ref_linesize[c]; int width = td->planewidth[c]; int height = td->planeheight[c]; - const int slice_start = ((height >> 2) * jobnr) / nb_jobs; - const int slice_end = ((height >> 2) * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height >> 2, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height >> 2, jobnr + 1, nb_jobs); const int ystart = FFMAX(1, slice_start); int z = ystart - 1; double ssim = 0.0; diff --git a/libavfilter/vf_stereo3d.c b/libavfilter/vf_stereo3d.c index da0681077..e3a3fc134 100644 --- a/libavfilter/vf_stereo3d.c +++ b/libavfilter/vf_stereo3d.c @@ -615,8 +615,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) AVFrame *iright = td->iright; AVFrame *out = td->out; int height = s->out.height; - int start = (height * jobnr ) / nb_jobs; - int end = (height * (jobnr+1)) / nb_jobs; + int start = ff_slice_pos(height, jobnr, nb_jobs); + int end = ff_slice_pos(height, jobnr + 1, nb_jobs); const int **ana_matrix = s->ana_matrix; s->dsp.anaglyph(out->data[0] + out->linesize[0] * start, diff --git a/libavfilter/vf_super2xsai.c b/libavfilter/vf_super2xsai.c index cf3aaebd6..7fc6d9b35 100644 --- a/libavfilter/vf_super2xsai.c +++ b/libavfilter/vf_super2xsai.c @@ -76,8 +76,8 @@ static int super2xsai(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const uint32_t lo_pixel_mask = s->lo_pixel_mask; const uint32_t q_hi_pixel_mask = s->q_hi_pixel_mask; const uint32_t q_lo_pixel_mask = s->q_lo_pixel_mask; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); /* Point to the first 4 lines, first line is duplicated */ src_line[0] = src + src_linesize*FFMAX(slice_start - 1, 0); diff --git a/libavfilter/vf_threshold.c b/libavfilter/vf_threshold.c index 633deb947..5a1d37736 100644 --- a/libavfilter/vf_threshold.c +++ b/libavfilter/vf_threshold.c @@ -86,8 +86,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) for (int p = 0; p < s->nb_planes; p++) { const int h = s->height[p]; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); if (!(s->planes & (1 << p))) { av_image_copy_plane(out->data[p] + slice_start * out->linesize[p], diff --git a/libavfilter/vf_thumbnail.c b/libavfilter/vf_thumbnail.c index b594996b9..c51a5d119 100644 --- a/libavfilter/vf_thumbnail.c +++ b/libavfilter/vf_thumbnail.c @@ -206,8 +206,8 @@ static int do_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) int *hist = s->thread_histogram + HIST_SIZE * jobnr; const int h = frame->height; const int w = frame->width; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); const uint8_t *p = frame->data[0] + slice_start * frame->linesize[0]; memset(hist, 0, sizeof(*hist) * HIST_SIZE); @@ -252,8 +252,8 @@ static int do_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) break; default: for (int plane = 0; plane < s->planes; plane++) { - const int slice_start = (s->planeheight[plane] * jobnr) / nb_jobs; - const int slice_end = (s->planeheight[plane] * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(s->planeheight[plane], jobnr, nb_jobs); + const int slice_end = ff_slice_pos(s->planeheight[plane], jobnr + 1, nb_jobs); const uint8_t *p = frame->data[plane] + slice_start * frame->linesize[plane]; const ptrdiff_t linesize = frame->linesize[plane]; const int planewidth = s->planewidth[plane]; diff --git a/libavfilter/vf_tonemap.c b/libavfilter/vf_tonemap.c index 54811ca40..c5be4b151 100644 --- a/libavfilter/vf_tonemap.c +++ b/libavfilter/vf_tonemap.c @@ -185,8 +185,8 @@ static int tonemap_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs AVFrame *in = td->in; AVFrame *out = td->out; const AVPixFmtDescriptor *desc = td->desc; - const int slice_start = (in->height * jobnr) / nb_jobs; - const int slice_end = (in->height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(in->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(in->height, jobnr + 1, nb_jobs); double peak = td->peak; for (int y = slice_start; y < slice_end; y++) diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c index c457b01a4..62c222f3c 100644 --- a/libavfilter/vf_transpose.c +++ b/libavfilter/vf_transpose.c @@ -282,8 +282,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int inh = AV_CEIL_RSHIFT(in->height, vsub); int outw = AV_CEIL_RSHIFT(out->width, hsub); int outh = AV_CEIL_RSHIFT(out->height, vsub); - int start = (outh * jobnr ) / nb_jobs; - int end = (outh * (jobnr+1)) / nb_jobs; + int start = ff_slice_pos(outh, jobnr, nb_jobs); + int end = ff_slice_pos(outh, jobnr + 1, nb_jobs); uint8_t *dst, *src; int dstlinesize, srclinesize; int x, y; diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c index 71d40447c..c45f19a90 100644 --- a/libavfilter/vf_unsharp.c +++ b/libavfilter/vf_unsharp.c @@ -110,8 +110,8 @@ static int name##_##nbits(AVFilterContext *ctx, void *arg, int jobnr, int nb_job const int height = td->height; \ const int sc_offset = jobnr * 2 * steps_y; \ const int sr_offset = jobnr * (MAX_MATRIX_SIZE - 1); \ - const int slice_start = (height * jobnr) / nb_jobs; \ - const int slice_end = (height * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); \ \ int32_t res; \ int x, y, z; \ diff --git a/libavfilter/vf_v360.c b/libavfilter/vf_v360.c index a08279867..3a1b19e9c 100644 --- a/libavfilter/vf_v360.c +++ b/libavfilter/vf_v360.c @@ -308,13 +308,13 @@ static int remap##ws##_##bits##bit_slice(AVFilterContext *ctx, void *arg, int jo const int width = s->pr_width[plane]; \ const int height = s->pr_height[plane]; \ \ - const int slice_start = (height * jobnr ) / nb_jobs; \ - const int slice_end = (height * (jobnr + 1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); \ \ for (int y = slice_start; y < slice_end && !mask; y++) { \ - const int16_t *const u = r->u[map] + (y - slice_start) * uv_linesize * ws * ws; \ - const int16_t *const v = r->v[map] + (y - slice_start) * uv_linesize * ws * ws; \ - const int16_t *const ker = r->ker[map] + (y - slice_start) * uv_linesize * ws * ws; \ + const int16_t *const u = r->u[map] + (y - slice_start) * (int64_t)uv_linesize * ws * ws; \ + const int16_t *const v = r->v[map] + (y - slice_start) * (int64_t)uv_linesize * ws * ws; \ + const int16_t *const ker = r->ker[map] + (y - slice_start) * (int64_t)uv_linesize * ws * ws;\ \ s->remap_line(dst + y * out_linesize, width, src, in_linesize, u, v, ker); \ } \ @@ -4246,8 +4246,8 @@ static int v360_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const int height = s->pr_height[p]; const int in_width = s->inplanewidth[p]; const int in_height = s->inplaneheight[p]; - const int slice_start = (height * jobnr ) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const int elements = s->elements; float du, dv; float vec[3]; @@ -4255,9 +4255,9 @@ static int v360_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) for (int j = slice_start; j < slice_end; j++) { for (int i = 0; i < width; i++) { - int16_t *u = r->u[p] + ((j - slice_start) * uv_linesize + i) * elements; - int16_t *v = r->v[p] + ((j - slice_start) * uv_linesize + i) * elements; - int16_t *ker = r->ker[p] + ((j - slice_start) * uv_linesize + i) * elements; + int16_t *u = r->u[p] + ((j - slice_start) * (int64_t)uv_linesize + i) * elements; + int16_t *v = r->v[p] + ((j - slice_start) * (int64_t)uv_linesize + i) * elements; + int16_t *ker = r->ker[p] + ((j - slice_start) * (int64_t)uv_linesize + i) * elements; uint8_t *mask8 = (p || !r->mask) ? NULL : r->mask + ((j - slice_start) * s->pr_width[0] + i); uint16_t *mask16 = (p || !r->mask) ? NULL : (uint16_t *)r->mask + ((j - slice_start) * s->pr_width[0] + i); int in_mask, out_mask; @@ -4295,6 +4295,20 @@ static int v360_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) return 0; } +static int get_output_dimension(AVFilterContext *ctx, const char *name, + float val, int *dim) +{ + if (!isfinite(val) || val < 1.f || val > INT16_MAX) { + av_log(ctx, AV_LOG_ERROR, + "Output %s %g is outside the allowed range [1, %d].\n", + name, val, INT16_MAX); + return AVERROR(EINVAL); + } + + *dim = lrintf(val); + return 0; +} + static int config_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; @@ -4465,6 +4479,15 @@ static int config_output(AVFilterLink *outlink) if (s->in_transpose) FFSWAP(int, s->in_width, s->in_height); + // The remap code stores input coordinates in int16_t + if (s->in_width < 1 || s->in_width > INT16_MAX || + s->in_height < 1 || s->in_height > INT16_MAX) { + av_log(ctx, AV_LOG_ERROR, + "Input dimensions %dx%d are outside the allowed range [1, %d].\n", + s->in_width, s->in_height, INT16_MAX); + return AVERROR(EINVAL); + } + switch (s->in) { case EQUIRECTANGULAR: s->in_transform = xyz_to_equirect; @@ -4782,11 +4805,17 @@ static int config_output(AVFilterLink *outlink) if (s->width > 0 && s->height <= 0 && s->h_fov > 0.f && s->v_fov > 0.f && s->out == FLAT && s->d_fov == 0.f) { w = s->width; - h = w / tanf(s->h_fov * M_PI / 360.f) * tanf(s->v_fov * M_PI / 360.f); + err = get_output_dimension(ctx, "height", + w / tanf(s->h_fov * M_PI / 360.f) * tanf(s->v_fov * M_PI / 360.f), &h); + if (err < 0) + return err; } else if (s->width <= 0 && s->height > 0 && s->h_fov > 0.f && s->v_fov > 0.f && s->out == FLAT && s->d_fov == 0.f) { h = s->height; - w = h / tanf(s->v_fov * M_PI / 360.f) * tanf(s->h_fov * M_PI / 360.f); + err = get_output_dimension(ctx, "width", + h / tanf(s->v_fov * M_PI / 360.f) * tanf(s->h_fov * M_PI / 360.f), &w); + if (err < 0) + return err; } else if (s->width > 0 && s->height > 0) { w = s->width; h = s->height; @@ -4801,6 +4830,13 @@ static int config_output(AVFilterLink *outlink) FFSWAP(int, w, h); } + if (w < 1 || w > INT16_MAX || h < 1 || h > INT16_MAX) { + av_log(ctx, AV_LOG_ERROR, + "Output dimensions %dx%d are outside the allowed range [1, %d].\n", + w, h, INT16_MAX); + return AVERROR(EINVAL); + } + s->width = w; s->height = h; diff --git a/libavfilter/vf_varblur.c b/libavfilter/vf_varblur.c index 6a9aa89ce..74efa0c6b 100644 --- a/libavfilter/vf_varblur.c +++ b/libavfilter/vf_varblur.c @@ -215,8 +215,8 @@ static int blur_planes(AVFilterContext *ctx, void *arg, for (int plane = 0; plane < s->nb_planes; plane++) { const int height = s->planeheight[plane]; - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const int width = s->planewidth[plane]; const int linesize = in->linesize[plane]; const int dst_linesize = out->linesize[plane]; diff --git a/libavfilter/vf_vibrance.c b/libavfilter/vf_vibrance.c index 94c3d569c..295e58241 100644 --- a/libavfilter/vf_vibrance.c +++ b/libavfilter/vf_vibrance.c @@ -75,8 +75,8 @@ static int vibrance_slice8(AVFilterContext *avctx, void *arg, int jobnr, int nb_ const float sgintensity = alternate * FFSIGN(gintensity); const float sbintensity = alternate * FFSIGN(bintensity); const float srintensity = alternate * FFSIGN(rintensity); - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t glinesize = frame->linesize[0]; const ptrdiff_t blinesize = frame->linesize[1]; const ptrdiff_t rlinesize = frame->linesize[2]; @@ -152,8 +152,8 @@ static int vibrance_slice16(AVFilterContext *avctx, void *arg, int jobnr, int nb const float sgintensity = alternate * FFSIGN(gintensity); const float sbintensity = alternate * FFSIGN(bintensity); const float srintensity = alternate * FFSIGN(rintensity); - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t gslinesize = in->linesize[0] / 2; const ptrdiff_t bslinesize = in->linesize[1] / 2; const ptrdiff_t rslinesize = in->linesize[2] / 2; @@ -232,8 +232,8 @@ static int vibrance_slice8p(AVFilterContext *avctx, void *arg, int jobnr, int nb const float sgintensity = alternate * FFSIGN(gintensity); const float sbintensity = alternate * FFSIGN(bintensity); const float srintensity = alternate * FFSIGN(rintensity); - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t linesize = frame->linesize[0]; const ptrdiff_t slinesize = in->linesize[0]; const uint8_t *src = in->data[0] + slice_start * slinesize; @@ -298,8 +298,8 @@ static int vibrance_slice16p(AVFilterContext *avctx, void *arg, int jobnr, int n const float sgintensity = alternate * FFSIGN(gintensity); const float sbintensity = alternate * FFSIGN(bintensity); const float srintensity = alternate * FFSIGN(rintensity); - const int slice_start = (height * jobnr) / nb_jobs; - const int slice_end = (height * (jobnr + 1)) / nb_jobs; + const int slice_start = ff_slice_pos(height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(height, jobnr + 1, nb_jobs); const ptrdiff_t linesize = frame->linesize[0] / 2; const ptrdiff_t slinesize = in->linesize[0] / 2; const uint16_t *src = (const uint16_t *)in->data[0] + slice_start * slinesize; diff --git a/libavfilter/vf_vif.c b/libavfilter/vf_vif.c index 6ec8a8d06..64eb39699 100644 --- a/libavfilter/vf_vif.c +++ b/libavfilter/vf_vif.c @@ -215,8 +215,8 @@ static int vif_filter1d(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) int dst_stride = td->dst_stride; int filt_w = td->filter_width; float *temp = td->temp[jobnr]; - const int slice_start = (h * jobnr) / nb_jobs; - const int slice_end = (h * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); for (int i = slice_start; i < slice_end; i++) { /** Vertical pass. */ diff --git a/libavfilter/vf_w3fdif.c b/libavfilter/vf_w3fdif.c index afde426f1..465453db2 100644 --- a/libavfilter/vf_w3fdif.c +++ b/libavfilter/vf_w3fdif.c @@ -378,8 +378,8 @@ static int deinterlace_plane_slice(AVFilterContext *ctx, void *arg, const int cur_line_stride = cur->linesize[plane]; const int adj_line_stride = adj->linesize[plane]; const int dst_line_stride = out->linesize[plane]; - const int start = (height * jobnr) / nb_jobs; - const int end = (height * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(height, jobnr, nb_jobs); + const int end = ff_slice_pos(height, jobnr + 1, nb_jobs); const int max = s->max; const int interlaced = !!(cur->flags & AV_FRAME_FLAG_INTERLACED); const int tff = s->field == (s->parity == -1 ? interlaced ? !!(cur->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) : 1 : diff --git a/libavfilter/vf_waveform.c b/libavfilter/vf_waveform.c index 4753999d0..8c8fdae79 100644 --- a/libavfilter/vf_waveform.c +++ b/libavfilter/vf_waveform.c @@ -705,10 +705,10 @@ static av_always_inline void lowpass16(WaveformContext *s, const int max = limit - intensity; const int src_h = AV_CEIL_RSHIFT(in->height, shift_h); const int src_w = AV_CEIL_RSHIFT(in->width, shift_w); - const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; - const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; - const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; - const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; + const int sliceh_start = !column ? ff_slice_pos(src_h, jobnr, nb_jobs) : 0; + const int sliceh_end = !column ? ff_slice_pos(src_h, jobnr + 1, nb_jobs) : src_h; + const int slicew_start = column ? ff_slice_pos(src_w, jobnr, nb_jobs) : 0; + const int slicew_end = column ? ff_slice_pos(src_w, jobnr + 1, nb_jobs) : src_w; const int step = column ? 1 << shift_w : 1 << shift_h; const uint16_t *src_data = (const uint16_t *)in->data[plane] + sliceh_start * src_linesize; uint16_t *dst_data = (uint16_t *)out->data[dplane] + (offset_y + sliceh_start * step) * dst_linesize + offset_x; @@ -842,10 +842,10 @@ static av_always_inline void lowpass(WaveformContext *s, const int max = 255 - intensity; const int src_h = AV_CEIL_RSHIFT(in->height, shift_h); const int src_w = AV_CEIL_RSHIFT(in->width, shift_w); - const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; - const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; - const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; - const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; + const int sliceh_start = !column ? ff_slice_pos(src_h, jobnr, nb_jobs) : 0; + const int sliceh_end = !column ? ff_slice_pos(src_h, jobnr + 1, nb_jobs) : src_h; + const int slicew_start = column ? ff_slice_pos(src_w, jobnr, nb_jobs) : 0; + const int slicew_end = column ? ff_slice_pos(src_w, jobnr + 1, nb_jobs) : src_w; const int step = column ? 1 << shift_w : 1 << shift_h; const uint8_t *src_data = in->data[plane] + sliceh_start * src_linesize; uint8_t *dst_data = out->data[dplane] + (offset_y + sliceh_start * step) * dst_linesize + offset_x; @@ -986,10 +986,10 @@ static av_always_inline void flat16(WaveformContext *s, const int mid = s->max / 2; const int src_h = in->height; const int src_w = in->width; - const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; - const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; - const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; - const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; + const int sliceh_start = !column ? ff_slice_pos(src_h, jobnr, nb_jobs) : 0; + const int sliceh_end = !column ? ff_slice_pos(src_h, jobnr + 1, nb_jobs) : src_h; + const int slicew_start = column ? ff_slice_pos(src_w, jobnr, nb_jobs) : 0; + const int slicew_end = column ? ff_slice_pos(src_w, jobnr + 1, nb_jobs) : src_w; int x, y; if (column) { @@ -1123,10 +1123,10 @@ static av_always_inline void flat(WaveformContext *s, const int max = 255 - intensity; const int src_h = in->height; const int src_w = in->width; - const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; - const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; - const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; - const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; + const int sliceh_start = !column ? ff_slice_pos(src_h, jobnr, nb_jobs) : 0; + const int sliceh_end = !column ? ff_slice_pos(src_h, jobnr + 1, nb_jobs) : src_h; + const int slicew_start = column ? ff_slice_pos(src_w, jobnr, nb_jobs) : 0; + const int slicew_end = column ? ff_slice_pos(src_w, jobnr + 1, nb_jobs) : src_w; int x, y; if (column) { @@ -1269,10 +1269,10 @@ static int name(AVFilterContext *ctx, const int mid = s->max / 2; \ const int src_h = in->height; \ const int src_w = in->width; \ - const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; \ - const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; \ - const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; \ - const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; \ + const int sliceh_start = !column ? ff_slice_pos(src_h, jobnr, nb_jobs) : 0; \ + const int sliceh_end = !column ? ff_slice_pos(src_h, jobnr + 1, nb_jobs) : src_h; \ + const int slicew_start = column ? ff_slice_pos(src_w, jobnr, nb_jobs) : 0; \ + const int slicew_end = column ? ff_slice_pos(src_w, jobnr + 1, nb_jobs) : src_w; \ int x, y; \ \ if (column) { \ @@ -1386,10 +1386,10 @@ static int name(AVFilterContext *ctx, int offset_x = td->offset_x; \ const int src_h = in->height; \ const int src_w = in->width; \ - const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; \ - const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; \ - const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; \ - const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; \ + const int sliceh_start = !column ? ff_slice_pos(src_h, jobnr, nb_jobs) : 0; \ + const int sliceh_end = !column ? ff_slice_pos(src_h, jobnr + 1, nb_jobs) : src_h; \ + const int slicew_start = column ? ff_slice_pos(src_w, jobnr, nb_jobs) : 0; \ + const int slicew_end = column ? ff_slice_pos(src_w, jobnr + 1, nb_jobs) : src_w; \ const int intensity = s->intensity; \ const int plane = s->desc->comp[component].plane; \ const int c0_linesize = in->linesize[ plane + 0 ]; \ @@ -1550,10 +1550,10 @@ static av_always_inline void chroma16(WaveformContext *s, const int c1_shift_h = s->shift_h[(component + 2) % s->ncomp]; const int src_h = in->height; const int src_w = in->width; - const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; - const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; - const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; - const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; + const int sliceh_start = !column ? ff_slice_pos(src_h, jobnr, nb_jobs) : 0; + const int sliceh_end = !column ? ff_slice_pos(src_h, jobnr + 1, nb_jobs) : src_h; + const int slicew_start = column ? ff_slice_pos(src_w, jobnr, nb_jobs) : 0; + const int slicew_end = column ? ff_slice_pos(src_w, jobnr + 1, nb_jobs) : src_w; int x, y; if (column) { @@ -1646,10 +1646,10 @@ static av_always_inline void chroma(WaveformContext *s, const int plane = s->desc->comp[component].plane; const int src_h = in->height; const int src_w = in->width; - const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; - const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; - const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; - const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; + const int sliceh_start = !column ? ff_slice_pos(src_h, jobnr, nb_jobs) : 0; + const int sliceh_end = !column ? ff_slice_pos(src_h, jobnr + 1, nb_jobs) : src_h; + const int slicew_start = column ? ff_slice_pos(src_w, jobnr, nb_jobs) : 0; + const int slicew_end = column ? ff_slice_pos(src_w, jobnr + 1, nb_jobs) : src_w; const int c0_linesize = in->linesize[(plane + 1) % s->ncomp]; const int c1_linesize = in->linesize[(plane + 2) % s->ncomp]; const int dst_linesize = out->linesize[plane]; @@ -1751,10 +1751,10 @@ static av_always_inline void color16(WaveformContext *s, const int limit = s->max - 1; const int src_h = in->height; const int src_w = in->width; - const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; - const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; - const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; - const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; + const int sliceh_start = !column ? ff_slice_pos(src_h, jobnr, nb_jobs) : 0; + const int sliceh_end = !column ? ff_slice_pos(src_h, jobnr + 1, nb_jobs) : src_h; + const int slicew_start = column ? ff_slice_pos(src_w, jobnr, nb_jobs) : 0; + const int slicew_end = column ? ff_slice_pos(src_w, jobnr + 1, nb_jobs) : src_w; const int c0_linesize = in->linesize[ plane + 0 ] / 2; const int c1_linesize = in->linesize[(plane + 1) % s->ncomp] / 2; const int c2_linesize = in->linesize[(plane + 2) % s->ncomp] / 2; @@ -1883,10 +1883,10 @@ static av_always_inline void color(WaveformContext *s, const int plane = s->desc->comp[component].plane; const int src_h = in->height; const int src_w = in->width; - const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; - const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; - const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; - const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; + const int sliceh_start = !column ? ff_slice_pos(src_h, jobnr, nb_jobs) : 0; + const int sliceh_end = !column ? ff_slice_pos(src_h, jobnr + 1, nb_jobs) : src_h; + const int slicew_start = column ? ff_slice_pos(src_w, jobnr, nb_jobs) : 0; + const int slicew_end = column ? ff_slice_pos(src_w, jobnr + 1, nb_jobs) : src_w; const int c0_linesize = in->linesize[ plane + 0 ]; const int c1_linesize = in->linesize[(plane + 1) % s->ncomp]; const int c2_linesize = in->linesize[(plane + 2) % s->ncomp]; @@ -2017,10 +2017,10 @@ static av_always_inline void acolor16(WaveformContext *s, const int max = limit - intensity; const int src_h = in->height; const int src_w = in->width; - const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; - const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; - const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; - const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; + const int sliceh_start = !column ? ff_slice_pos(src_h, jobnr, nb_jobs) : 0; + const int sliceh_end = !column ? ff_slice_pos(src_h, jobnr + 1, nb_jobs) : src_h; + const int slicew_start = column ? ff_slice_pos(src_w, jobnr, nb_jobs) : 0; + const int slicew_end = column ? ff_slice_pos(src_w, jobnr + 1, nb_jobs) : src_w; const int c0_shift_h = s->shift_h[ component + 0 ]; const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp]; const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp]; @@ -2149,10 +2149,10 @@ static av_always_inline void acolor(WaveformContext *s, const int plane = s->desc->comp[component].plane; const int src_h = in->height; const int src_w = in->width; - const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; - const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; - const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; - const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; + const int sliceh_start = !column ? ff_slice_pos(src_h, jobnr, nb_jobs) : 0; + const int sliceh_end = !column ? ff_slice_pos(src_h, jobnr + 1, nb_jobs) : src_h; + const int slicew_start = column ? ff_slice_pos(src_w, jobnr, nb_jobs) : 0; + const int slicew_end = column ? ff_slice_pos(src_w, jobnr + 1, nb_jobs) : src_w; const int c0_shift_w = s->shift_w[ component + 0 ]; const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp]; const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp]; diff --git a/libavfilter/vf_weave.c b/libavfilter/vf_weave.c index 91c98e0e6..957fbb599 100644 --- a/libavfilter/vf_weave.c +++ b/libavfilter/vf_weave.c @@ -114,8 +114,8 @@ static int weave_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) for (int i = 0; i < s->nb_planes; i++) { const int height = s->planeheight[i]; - const int start = (height * jobnr) / nb_jobs; - const int end = (height * (jobnr+1)) / nb_jobs; + const int start = ff_slice_pos(height, jobnr, nb_jobs); + const int end = ff_slice_pos(height, jobnr + 1, nb_jobs); const int compensation = 2*end > s->outheight[i]; av_image_copy_plane(out->data[i] + out->linesize[i] * field1 + diff --git a/libavfilter/vf_xbr.c b/libavfilter/vf_xbr.c index c9a4bc5be..b2237749f 100644 --- a/libavfilter/vf_xbr.c +++ b/libavfilter/vf_xbr.c @@ -219,8 +219,8 @@ static av_always_inline void xbr_filter(const ThreadData *td, int jobnr, int nb_ const AVFrame *input = td->in; AVFrame *output = td->out; const uint32_t *r2y = td->rgbtoyuv; - const int slice_start = (input->height * jobnr ) / nb_jobs; - const int slice_end = (input->height * (jobnr+1)) / nb_jobs; + const int slice_start = ff_slice_pos(input->height, jobnr, nb_jobs); + const int slice_end = ff_slice_pos(input->height, jobnr + 1, nb_jobs); const int nl = output->linesize[0] >> 2; const int nl1 = nl + nl; const int nl2 = nl1 + nl; diff --git a/libavfilter/vf_xfade.c b/libavfilter/vf_xfade.c index 4517e4e6b..53dcf3e1e 100644 --- a/libavfilter/vf_xfade.c +++ b/libavfilter/vf_xfade.c @@ -2193,8 +2193,8 @@ static int xfade_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) XFadeContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; ThreadData *td = arg; - int slice_start = (outlink->h * jobnr ) / nb_jobs; - int slice_end = (outlink->h * (jobnr+1)) / nb_jobs; + int slice_start = ff_slice_pos(outlink->h, jobnr, nb_jobs); + int slice_end = ff_slice_pos(outlink->h, jobnr + 1, nb_jobs); s->transitionf(ctx, td->xf[0], td->xf[1], td->out, td->progress, slice_start, slice_end, jobnr); diff --git a/libavfilter/vf_xmedian.c b/libavfilter/vf_xmedian.c index f411d063f..7f64a96c9 100644 --- a/libavfilter/vf_xmedian.c +++ b/libavfilter/vf_xmedian.c @@ -145,8 +145,8 @@ static int median_frames ## name(AVFilterContext *ctx, void *arg, int jobnr, int type values[256]; \ \ for (int p = 0; p < s->nb_planes; p++) { \ - const int slice_start = (s->height[p] * jobnr) / nb_jobs; \ - const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs; \ + const int slice_start = ff_slice_pos(s->height[p], jobnr, nb_jobs); \ + const int slice_end = ff_slice_pos(s->height[p], jobnr + 1, nb_jobs); \ const int width = s->width[p]; \ type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \ ptrdiff_t dst_linesize = out->linesize[p] / sizeof(type); \ diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index 9e4f8d5b4..41ba056ad 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -193,8 +193,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) int refs = s->cur->linesize[td->plane]; int df = (s->csp->comp[td->plane].depth + 7) / 8; int pix_3 = 3 * df; - int slice_start = (td->h * jobnr ) / nb_jobs; - int slice_end = (td->h * (jobnr+1)) / nb_jobs; + int slice_start = ff_slice_pos(td->h, jobnr, nb_jobs); + int slice_end = ff_slice_pos(td->h, jobnr + 1, nb_jobs); int y; int edge = 3 + MAX_ALIGN / df - 1; diff --git a/libavfilter/vf_yaepblur.c b/libavfilter/vf_yaepblur.c index 50fe78df5..59f3501f3 100644 --- a/libavfilter/vf_yaepblur.c +++ b/libavfilter/vf_yaepblur.c @@ -104,8 +104,8 @@ static int pre_calculate_row_##name(AVFilterContext *ctx, void *arg, \ const int linesize = td->src_linesize / sizeof(type); \ const int sat_linesize = s->sat_linesize; \ \ - const int starty = height * jobnr / nb_jobs; \ - const int endy = height * (jobnr+1) / nb_jobs; \ + const int starty = ff_slice_pos(height, jobnr, nb_jobs); \ + const int endy = ff_slice_pos(height, jobnr + 1, nb_jobs); \ \ uint64_t *sat = s->sat + (starty + 1) * sat_linesize; \ uint64_t *square_sat = s->square_sat + (starty + 1) * sat_linesize; \ @@ -139,8 +139,8 @@ static int pre_calculate_col(AVFilterContext *ctx, void *arg, const int height = td->height; const int sat_linesize = s->sat_linesize; - const int startx = width * jobnr / nb_jobs; - const int endx = width * (jobnr + 1) / nb_jobs; + const int startx = ff_slice_pos(width, jobnr, nb_jobs); + const int endx = ff_slice_pos(width, jobnr + 1, nb_jobs); uint64_t *sat, *square_sat; int x, y; @@ -178,8 +178,8 @@ static int filter_slice_##name(AVFilterContext *ctx, void *arg, int jobnr, int n const type *src = (const type *)td->src; \ type *dst = (type *)td->dst; \ \ - const int starty = height * jobnr / nb_jobs; \ - const int endy = height * (jobnr + 1) / nb_jobs; \ + const int starty = ff_slice_pos(height, jobnr, nb_jobs); \ + const int endy = ff_slice_pos(height, jobnr + 1, nb_jobs); \ \ int x, y; \ int lower_x, higher_x; \ diff --git a/libavfilter/x86/vf_lut3d_init.c b/libavfilter/x86/vf_lut3d_init.c index db1a152f5..d149f6639 100644 --- a/libavfilter/x86/vf_lut3d_init.c +++ b/libavfilter/x86/vf_lut3d_init.c @@ -21,6 +21,7 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/x86/cpu.h" +#include "libavfilter/filters.h" #include "libavfilter/lut3d.h" #define DEFINE_INTERP_FUNC(name, format, opt) \ @@ -33,8 +34,8 @@ static int interp_##name##_##format##_##opt(AVFilterContext *ctx, void *arg, int AVFrame *in = td->in; \ AVFrame *out = td->out; \ int has_alpha = in->linesize[3] && out != in; \ - int slice_start = (in->height * jobnr ) / nb_jobs; \ - int slice_end = (in->height * (jobnr+1)) / nb_jobs; \ + int slice_start = ff_slice_pos(in->height, jobnr, nb_jobs); \ + int slice_end = ff_slice_pos(in->height, jobnr + 1, nb_jobs); \ ff_interp_##name##_##format##_##opt(lut3d, prelut, in, out, slice_start, slice_end, has_alpha); \ return 0; \ } diff --git a/libavformat/assenc.c b/libavformat/assenc.c index 75c19afd0..b94820388 100644 --- a/libavformat/assenc.c +++ b/libavformat/assenc.c @@ -186,7 +186,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) if (hh2 > 9) hh2 = 9, mm2 = 59, ss2 = 59, ms2 = 99; text_len = strlen(p); - while (text_len > 0 && p[text_len - 1] == '\r' || p[text_len - 1] == '\n') + while (text_len > 0 && (p[text_len - 1] == '\r' || p[text_len - 1] == '\n')) text_len--; dialogue->line = av_asprintf("%s%ld,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%.*s", diff --git a/libavformat/avc.c b/libavformat/avc.c index e4040928c..84a3c3d0f 100644 --- a/libavformat/avc.c +++ b/libavformat/avc.c @@ -23,6 +23,7 @@ #include "libavutil/mem.h" #include "libavcodec/h264.h" #include "libavcodec/get_bits.h" +#include "libavcodec/golomb.h" #include "avio.h" #include "avc.h" #include "avio_internal.h" @@ -192,19 +193,6 @@ static const AVRational avc_sample_aspect_ratio[17] = { { 2, 1 }, }; -static inline int get_ue_golomb(GetBitContext *gb) { - int i; - for (i = 0; i < 32 && !get_bits1(gb); i++) - ; - return get_bitsz(gb, i) + (1 << i) - 1; -} - -static inline int get_se_golomb(GetBitContext *gb) { - int v = get_ue_golomb(gb) + 1; - int sign = -(v & 1); - return ((v >> 1) ^ sign) - sign; -} - int ff_avc_decode_sps(H264SPS *sps, const uint8_t *buf, int buf_size) { int i, j, ret, rbsp_size, aspect_ratio_idc, pic_order_cnt_type; @@ -233,19 +221,19 @@ int ff_avc_decode_sps(H264SPS *sps, const uint8_t *buf, int buf_size) sps->constraint_set_flags |= get_bits1(&gb) << 5; // constraint_set5_flag skip_bits(&gb, 2); // reserved_zero_2bits sps->level_idc = get_bits(&gb, 8); - sps->id = get_ue_golomb(&gb); + sps->id = get_ue_golomb_long(&gb); if (sps->profile_idc == 100 || sps->profile_idc == 110 || sps->profile_idc == 122 || sps->profile_idc == 244 || sps->profile_idc == 44 || sps->profile_idc == 83 || sps->profile_idc == 86 || sps->profile_idc == 118 || sps->profile_idc == 128 || sps->profile_idc == 138 || sps->profile_idc == 139 || sps->profile_idc == 134) { - sps->chroma_format_idc = get_ue_golomb(&gb); // chroma_format_idc + sps->chroma_format_idc = get_ue_golomb_long(&gb); // chroma_format_idc if (sps->chroma_format_idc == 3) { skip_bits1(&gb); // separate_colour_plane_flag } - sps->bit_depth_luma = get_ue_golomb(&gb) + 8; - sps->bit_depth_chroma = get_ue_golomb(&gb) + 8; + sps->bit_depth_luma = get_ue_golomb_long(&gb) + 8; + sps->bit_depth_chroma = get_ue_golomb_long(&gb) + 8; skip_bits1(&gb); // qpprime_y_zero_transform_bypass_flag if (get_bits1(&gb)) { // seq_scaling_matrix_present_flag for (i = 0; i < ((sps->chroma_format_idc != 3) ? 8 : 12); i++) { @@ -256,7 +244,7 @@ int ff_avc_decode_sps(H264SPS *sps, const uint8_t *buf, int buf_size) sizeOfScalingList = i < 6 ? 16 : 64; for (j = 0; j < sizeOfScalingList; j++) { if (nextScale != 0) { - delta_scale = get_se_golomb(&gb); + delta_scale = get_se_golomb_long(&gb); nextScale = (lastScale + delta_scale) & 0xff; } lastScale = nextScale == 0 ? lastScale : nextScale; @@ -269,24 +257,24 @@ int ff_avc_decode_sps(H264SPS *sps, const uint8_t *buf, int buf_size) sps->bit_depth_chroma = 8; } - get_ue_golomb(&gb); // log2_max_frame_num_minus4 - pic_order_cnt_type = get_ue_golomb(&gb); + get_ue_golomb_long(&gb); // log2_max_frame_num_minus4 + pic_order_cnt_type = get_ue_golomb_long(&gb); if (pic_order_cnt_type == 0) { - get_ue_golomb(&gb); // log2_max_pic_order_cnt_lsb_minus4 + get_ue_golomb_long(&gb); // log2_max_pic_order_cnt_lsb_minus4 } else if (pic_order_cnt_type == 1) { skip_bits1(&gb); // delta_pic_order_always_zero - get_se_golomb(&gb); // offset_for_non_ref_pic - get_se_golomb(&gb); // offset_for_top_to_bottom_field - num_ref_frames_in_pic_order_cnt_cycle = get_ue_golomb(&gb); + get_se_golomb_long(&gb); // offset_for_non_ref_pic + get_se_golomb_long(&gb); // offset_for_top_to_bottom_field + num_ref_frames_in_pic_order_cnt_cycle = get_ue_golomb_long(&gb); for (i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) - get_se_golomb(&gb); // offset_for_ref_frame + get_se_golomb_long(&gb); // offset_for_ref_frame } - get_ue_golomb(&gb); // max_num_ref_frames + get_ue_golomb_long(&gb); // max_num_ref_frames skip_bits1(&gb); // gaps_in_frame_num_value_allowed_flag - get_ue_golomb(&gb); // pic_width_in_mbs_minus1 - get_ue_golomb(&gb); // pic_height_in_map_units_minus1 + get_ue_golomb_long(&gb); // pic_width_in_mbs_minus1 + get_ue_golomb_long(&gb); // pic_height_in_map_units_minus1 sps->frame_mbs_only_flag = get_bits1(&gb); if (!sps->frame_mbs_only_flag) @@ -295,10 +283,10 @@ int ff_avc_decode_sps(H264SPS *sps, const uint8_t *buf, int buf_size) skip_bits1(&gb); // direct_8x8_inference_flag if (get_bits1(&gb)) { // frame_cropping_flag - get_ue_golomb(&gb); // frame_crop_left_offset - get_ue_golomb(&gb); // frame_crop_right_offset - get_ue_golomb(&gb); // frame_crop_top_offset - get_ue_golomb(&gb); // frame_crop_bottom_offset + get_ue_golomb_long(&gb); // frame_crop_left_offset + get_ue_golomb_long(&gb); // frame_crop_right_offset + get_ue_golomb_long(&gb); // frame_crop_top_offset + get_ue_golomb_long(&gb); // frame_crop_bottom_offset } if (get_bits1(&gb)) { // vui_parameters_present_flag diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 9a2ea7814..87261497d 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -109,6 +109,7 @@ struct representation { int64_t cur_seg_offset; int64_t cur_seg_size; struct fragment *cur_seg; + int n_open_failures; /* consecutive open_input failures since last good read */ /* Currently active Media Initialization Section */ struct fragment *init_section; @@ -153,6 +154,7 @@ typedef struct DASHContext { char *allowed_extensions; AVDictionary *avio_opts; int max_url_size; + int max_reload; char *cenc_decryption_key; char *cenc_decryption_keys; @@ -447,7 +449,7 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, av_freep(pb); av_dict_copy(&tmp, *opts, 0); av_dict_copy(&tmp, opts2, 0); - ret = ffio_open_whitelist(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp, s->protocol_whitelist, s->protocol_blacklist); + ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -1255,7 +1257,7 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) close_in = 1; av_dict_copy(&opts, c->avio_opts, 0); - ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ, c->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist); + ret = s->io_open(s, &in, url, AVIO_FLAG_READ, &opts); av_dict_free(&opts); if (ret < 0) return ret; @@ -1398,7 +1400,7 @@ cleanup: av_bprint_finalize(&buf, NULL); if (close_in) { - avio_close(in); + ff_format_io_close(s, &in); } return ret; } @@ -1619,6 +1621,7 @@ static struct fragment *get_current_fragment(struct representation *pls) struct fragment *seg = NULL; struct fragment *seg_ptr = NULL; DASHContext *c = pls->parent->priv_data; + int reload_count = 0; while (( !ff_check_interrupt(c->interrupt_callback)&& pls->n_fragments > 0)) { if (pls->cur_seq_no < pls->n_fragments) { @@ -1636,6 +1639,12 @@ static struct fragment *get_current_fragment(struct representation *pls) seg->url_offset = seg_ptr->url_offset; return seg; } else if (c->is_live) { + if (reload_count++ >= c->max_reload) { + av_log(pls->parent, AV_LOG_ERROR, + "Reached max manifest reloads (%d) at seq %"PRId64"\n", + c->max_reload, pls->cur_seq_no); + return NULL; + } refresh_manifest(pls->parent); } else { break; @@ -1826,9 +1835,17 @@ restart: goto end; } av_log(v->parent, AV_LOG_WARNING, "Failed to open fragment of playlist\n"); + if (++v->n_open_failures > c->max_reload) { + av_log(v->parent, AV_LOG_ERROR, + "Reached max consecutive fragment open failures (%d), giving up\n", + c->max_reload); + ret = AVERROR_EOF; + goto end; + } v->cur_seq_no++; goto restart; } + v->n_open_failures = 0; } if (v->init_sec_buf_read_offset < v->init_sec_data_len) { @@ -2084,6 +2101,8 @@ static int dash_read_header(AVFormatContext *s) if (ret) return ret; + if (rep->ctx->nb_streams == 0) + return AVERROR_PATCHWELCOME; rep->stream_index = stream_index; ++stream_index; } @@ -2102,6 +2121,8 @@ static int dash_read_header(AVFormatContext *s) if (ret) return ret; + if (rep->ctx->nb_streams == 0) + return AVERROR_PATCHWELCOME; rep->stream_index = stream_index; ++stream_index; } @@ -2120,6 +2141,8 @@ static int dash_read_header(AVFormatContext *s) if (ret) return ret; + if (rep->ctx->nb_streams == 0) + return AVERROR_PATCHWELCOME; rep->stream_index = stream_index; ++stream_index; } @@ -2379,6 +2402,8 @@ static const AVOption dash_options[] = { INT_MIN, INT_MAX, FLAGS}, { "cenc_decryption_key", "Media default decryption key (hex)", OFFSET(cenc_decryption_key), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN, INT_MAX, .flags = FLAGS }, { "cenc_decryption_keys", "Media decryption keys by KID (hex)", OFFSET(cenc_decryption_keys), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN, INT_MAX, .flags = FLAGS }, + { "max_reload", "Maximum number of manifest reloads in get_current_fragment() before giving up", + OFFSET(max_reload), AV_OPT_TYPE_INT, { .i64 = 100 }, 0, INT_MAX, FLAGS }, {NULL} }; diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index da7725fc3..1b9c6a601 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -490,7 +490,7 @@ static void dash_free(AVFormatContext *s) if (!c->single_file) ffio_free_dyn_buf(&os->ctx->pb); else - avio_close(os->ctx->pb); + ff_format_io_close(s, &os->ctx->pb); } ff_format_io_close(s, &os->out); avformat_free_context(os->ctx); @@ -1458,7 +1458,7 @@ static int dash_init(AVFormatContext *s) ret = s->io_open(s, &os->out, filename, AVIO_FLAG_WRITE, &opts); } else { ctx->url = av_strdup(filename); - ret = avio_open2(&ctx->pb, filename, AVIO_FLAG_WRITE, NULL, &opts); + ret = s->io_open(s, &ctx->pb, filename, AVIO_FLAG_WRITE, &opts); } av_dict_free(&opts); if (ret < 0) diff --git a/libavformat/demux.c b/libavformat/demux.c index a1909237f..555399720 100644 --- a/libavformat/demux.c +++ b/libavformat/demux.c @@ -368,7 +368,7 @@ fail: ff_id3v2_free_extra_meta(&id3v2_extra_meta); av_dict_free(&tmp); if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO)) - avio_closep(&s->pb); + ff_format_io_close(s, &s->pb); avformat_free_context(s); *ps = NULL; return ret; diff --git a/libavformat/dhav.c b/libavformat/dhav.c index b9adfc129..d705a5303 100644 --- a/libavformat/dhav.c +++ b/libavformat/dhav.c @@ -280,7 +280,7 @@ static int64_t get_duration(AVFormatContext *s) } } - if (pos < buffer_pos || pos + 20 > buffer_pos + buffer_size) + if (pos < buffer_pos || pos - buffer_pos > buffer_size - 20) goto fail; date = AV_RL32(buffer + (pos - buffer_pos) + 16); diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 6d6c54193..45fd1b2fb 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -1559,6 +1559,10 @@ skip: for (;;) { int track_size = size; + if (size < 0) { + ret = FFERROR_REDO; + goto leave; + } if (multitrack_type != MultitrackTypeOneTrack) { track_size = avio_rb24(s->pb); diff --git a/libavformat/ftp.c b/libavformat/ftp.c index 761dce812..3865177f9 100644 --- a/libavformat/ftp.c +++ b/libavformat/ftp.c @@ -100,6 +100,16 @@ static const AVClass ftp_context_class = { static int ftp_close(URLContext *h); +static int is_bad_string(const unsigned char *s) +{ + while(*s) { + if (*s < 0x20 || *s == 0x7F || *s == 0xFF) + return 1; + s++; + } + return 0; +} + static int ftp_getc(FTPContext *s) { int len; @@ -250,7 +260,7 @@ static int ftp_auth(FTPContext *s) static const int user_codes[] = {331, 230, 0}; static const int pass_codes[] = {230, 0}; - if (strpbrk(s->user, "\r\n")) + if (is_bad_string(s->user)) return AVERROR(EINVAL); err = snprintf(buf, sizeof(buf), "USER %s\r\n", s->user); if (err >= sizeof(buf)) @@ -259,7 +269,7 @@ static int ftp_auth(FTPContext *s) err = ftp_send_command(s, buf, user_codes, NULL); if (err == 331) { if (s->password) { - if (strpbrk(s->password, "\r\n")) + if (is_bad_string(s->password)) return AVERROR(EINVAL); err = snprintf(buf, sizeof(buf), "PASS %s\r\n", s->password); if (err >= sizeof(buf)) @@ -746,6 +756,11 @@ static int ftp_connect(URLContext *h, const char *url) av_free(s->path); s->path = newpath; + if (is_bad_string(s->path)) { + av_log(h, AV_LOG_ERROR, "Path contains non-printable characters\n"); + return AVERROR(EINVAL); + } + return 0; } @@ -1156,6 +1171,10 @@ static int ftp_move(URLContext *h_src, URLContext *h_dst) av_url_split(0, 0, 0, 0, 0, 0, 0, path, sizeof(path), h_dst->filename); + if (is_bad_string(path)) { + ret = AVERROR(EINVAL); + goto cleanup; + } ret = snprintf(command, sizeof(command), "RNTO %s\r\n", path); if (ret >= sizeof(command)) { ret = AVERROR(ENOSYS); diff --git a/libavformat/gxfenc.c b/libavformat/gxfenc.c index 43ffa9d45..023c20d4e 100644 --- a/libavformat/gxfenc.c +++ b/libavformat/gxfenc.c @@ -669,9 +669,12 @@ static int gxf_init_timecode(AVFormatContext *s, GXFTimecode *tc, const char *tc if (sscanf(tcstr, "%d:%d:%d%c%d", &tc->hh, &tc->mm, &tc->ss, &c, &tc->ff) != 5) { av_log(s, AV_LOG_ERROR, "unable to parse timecode, " "syntax: hh:mm:ss[:;.]ff\n"); - return -1; + return AVERROR(EINVAL); } + if (tc->hh > 31U || tc->mm > 255U || tc->ss > 255U || tc->ff > (255U >> (fields == 2))) + return AVERROR(EINVAL); + tc->color = 0; tc->drop = c != ':'; @@ -803,8 +806,11 @@ static int gxf_write_header(AVFormatContext *s) sc->order = s->nb_streams - st->index; } - if (tcr && vsc) - gxf_init_timecode(s, &gxf->tc, tcr->value, vsc->fields); + if (tcr && vsc) { + ret = gxf_init_timecode(s, &gxf->tc, tcr->value, vsc->fields); + if (ret < 0) + return ret; + } gxf_init_timecode_track(&gxf->timecode_track, vsc); gxf->flags |= 0x200000; // time code track is non-drop frame diff --git a/libavformat/hls.c b/libavformat/hls.c index 28c883097..2f7142fd4 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -452,6 +452,11 @@ static struct segment *new_init_section(struct playlist *pls, ptr = strchr(info->byterange, '@'); if (ptr) sec->url_offset = strtoll(ptr+1, NULL, 10); + if (sec->size < 0 || sec->url_offset < 0 || sec->size > INT64_MAX - sec->url_offset) { + av_freep(&sec->url); + av_free(sec); + return NULL; + } } else { /* the entire file is the init section */ sec->size = -1; @@ -958,9 +963,14 @@ static int parse_playlist(HLSContext *c, const char *url, goto fail; } if (av_strstart(ptr, "TIME-OFFSET=", &time_offset_value)) { - float offset = strtof(time_offset_value, NULL); - pls->start_time_offset = offset * AV_TIME_BASE; - pls->time_offset_flag = 1; + double offset = strtod(time_offset_value, NULL) * AV_TIME_BASE; + if (offset >= -0x1p63 && offset < 0x1p63) { + pls->start_time_offset = offset; + pls->time_offset_flag = 1; + } else { + av_log(c->ctx, AV_LOG_WARNING, "TIME-OFFSET value is" + "invalid, it will be ignored"); + } } else { av_log(c->ctx, AV_LOG_WARNING, "#EXT-X-START value is" "invalid, it will be ignored"); diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 957b9a5dd..b0740205d 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -703,7 +703,7 @@ static int do_encrypt(AVFormatContext *s, VariantStream *vs) return ret; avio_seek(pb, 0, SEEK_CUR); avio_write(pb, key, KEYSIZE); - avio_close(pb); + ff_format_io_close(s, &pb); } return 0; } @@ -1157,9 +1157,7 @@ static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs const char *end; double discont_program_date_time = 0; - if ((ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ, - &s->interrupt_callback, NULL, - s->protocol_whitelist, s->protocol_blacklist)) < 0) + if ((ret = s->io_open(s, &in, url, AVIO_FLAG_READ, NULL)) < 0) return ret; ff_get_chomp_line(in, line, sizeof(line)); @@ -1269,7 +1267,7 @@ static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs } fail: - avio_close(in); + ff_format_io_close(s, &in); return ret; } diff --git a/libavformat/http.c b/libavformat/http.c index 52073ffcb..b56ef5ebf 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -1189,6 +1189,8 @@ static int process_line(URLContext *h, char *line, int line_count, int *parsed_h method = p; while (*p && !av_isspace(*p)) p++; + if (!av_isspace(*p)) + return ff_http_averror(400, AVERROR(EIO)); *(p++) = '\0'; av_log(h, AV_LOG_TRACE, "Received method: %s\n", method); if (s->method) { @@ -1215,6 +1217,8 @@ static int process_line(URLContext *h, char *line, int line_count, int *parsed_h resource = p; while (*p && !av_isspace(*p)) p++; + if (!av_isspace(*p)) + return ff_http_averror(400, AVERROR(EIO)); *(p++) = '\0'; av_log(h, AV_LOG_TRACE, "Requested resource: %s\n", resource); if (!(s->resource = av_strdup(resource))) diff --git a/libavformat/iamf_parse.c b/libavformat/iamf_parse.c index 97a5c8a36..d74a8677d 100644 --- a/libavformat/iamf_parse.c +++ b/libavformat/iamf_parse.c @@ -816,6 +816,13 @@ static int audio_element_obu(void *s, IAMFContext *c, AVIOContext *pb, int len) } nb_substreams = ffio_read_leb(pbc); + /* Each substream consumes at least one byte (its leb128 id) from the + * remaining OBU buffer, so a count larger than that cannot be valid and + * would only serve to force an oversized allocation. */ + if (nb_substreams > len - avio_tell(pbc) || !nb_substreams) { + ret = AVERROR_INVALIDDATA; + goto fail; + } audio_element->codec_config_id = codec_config_id; audio_element->audio_element_id = audio_element_id; audio_element->substreams = av_calloc(nb_substreams, sizeof(*audio_element->substreams)); diff --git a/libavformat/iamf_writer.c b/libavformat/iamf_writer.c index 8d152c14a..ef7cecab2 100644 --- a/libavformat/iamf_writer.c +++ b/libavformat/iamf_writer.c @@ -90,12 +90,6 @@ static int populate_audio_roll_distance(IAMFCodecConfig *codec_config) codec_config->audio_roll_distance = -1; break; case AV_CODEC_ID_FLAC: - case AV_CODEC_ID_PCM_S16BE: - case AV_CODEC_ID_PCM_S24BE: - case AV_CODEC_ID_PCM_S32BE: - case AV_CODEC_ID_PCM_S16LE: - case AV_CODEC_ID_PCM_S24LE: - case AV_CODEC_ID_PCM_S32LE: codec_config->audio_roll_distance = 0; break; default: @@ -535,35 +529,12 @@ static int iamf_write_codec_config(const IAMFContext *iamf, avio_write(dyn_bc, codec_config->extradata, codec_config->extradata_size); break; case AV_CODEC_ID_PCM_S16LE: - avio_w8(dyn_bc, 1); - avio_w8(dyn_bc, 16); - avio_wb32(dyn_bc, codec_config->sample_rate); - break; case AV_CODEC_ID_PCM_S24LE: - avio_w8(dyn_bc, 1); - avio_w8(dyn_bc, 24); - avio_wb32(dyn_bc, codec_config->sample_rate); - break; case AV_CODEC_ID_PCM_S32LE: - avio_w8(dyn_bc, 1); - avio_w8(dyn_bc, 32); - avio_wb32(dyn_bc, codec_config->sample_rate); - break; case AV_CODEC_ID_PCM_S16BE: - avio_w8(dyn_bc, 0); - avio_w8(dyn_bc, 16); - avio_wb32(dyn_bc, codec_config->sample_rate); - break; case AV_CODEC_ID_PCM_S24BE: - avio_w8(dyn_bc, 0); - avio_w8(dyn_bc, 24); - avio_wb32(dyn_bc, codec_config->sample_rate); - break; case AV_CODEC_ID_PCM_S32BE: - avio_w8(dyn_bc, 0); - avio_w8(dyn_bc, 32); - avio_wb32(dyn_bc, codec_config->sample_rate); - break; + return AVERROR(ENOSYS); default: break; } diff --git a/libavformat/icecast.c b/libavformat/icecast.c index 3146d7f38..323d330e4 100644 --- a/libavformat/icecast.c +++ b/libavformat/icecast.c @@ -70,8 +70,14 @@ static const AVOption options[] = { static void cat_header(AVBPrint *bp, const char key[], const char value[]) { - if (NOT_EMPTY(value)) + if (NOT_EMPTY(value)) { + if (strpbrk(value, "\r\n")) { + av_log(NULL, AV_LOG_ERROR, + "Refusing to send '%s' header: value contains CR/LF\n", key); + return; + } av_bprintf(bp, "%s: %s\r\n", key, value); + } } static int icecast_close(URLContext *h) diff --git a/libavformat/iff.c b/libavformat/iff.c index 8dccd58b3..74362d29f 100644 --- a/libavformat/iff.c +++ b/libavformat/iff.c @@ -993,6 +993,8 @@ static int iff_read_packet(AVFormatContext *s, return AVERROR_EOF; ret = av_get_packet(pb, pkt, data_size); + if (ret < 0) + return ret; pkt->stream_index = iff->video_stream_index; pkt->pos = orig_pos; pkt->duration = get_anim_duration(pkt->data, pkt->size); diff --git a/libavformat/isom.h b/libavformat/isom.h index d7e138585..c7264defb 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -386,6 +386,7 @@ typedef struct MOVContext { int64_t idat_offset; int interleaved_read; AVDictionary* decryption_keys; + unsigned heif_icc_profile_items; } MOVContext; int ff_mp4_read_descr_len(AVIOContext *pb); diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 3ac81aa09..344e610e1 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1338,6 +1338,13 @@ static int ebml_parse(MatroskaDemuxContext *matroska, if ((unsigned)list->nb_elem + 1 >= UINT_MAX / syntax->list_elem_size) return AVERROR(ENOMEM); + if (syntax->id == MATROSKA_ID_TRACKENTRY && + list->nb_elem >= matroska->ctx->max_streams) { + av_log(matroska->ctx, AV_LOG_ERROR, + "Number of tracks exceeds max_streams (%d)\n", + matroska->ctx->max_streams); + return AVERROR(EINVAL); + } newelem = av_fast_realloc(list->elem, &list->alloc_elem_size, (list->nb_elem + 1) * syntax->list_elem_size); @@ -4459,7 +4466,8 @@ static CueDesc get_cue_desc(AVFormatContext *s, int64_t ts, int64_t cues_start) cue_desc.end_offset = cues_start - matroska->segment_start; } - if (cue_desc.end_time_ns < cue_desc.start_time_ns) + if (cue_desc.end_time_ns < cue_desc.start_time_ns || + cue_desc.end_time_ns - (uint64_t)cue_desc.start_time_ns > INT64_MAX) return (CueDesc) {-1, -1, -1, -1}; return cue_desc; @@ -4653,11 +4661,14 @@ static int64_t webm_dash_manifest_compute_bandwidth(AVFormatContext *s, int64_t bits_per_second = 0.0; do { int64_t desc_bytes = desc_end.end_offset - desc_beg.start_offset; - int64_t desc_ns = desc_end.end_time_ns - desc_beg.start_time_ns; double desc_sec, calc_bits_per_second, percent, mod_bits_per_second; if (desc_bytes <= 0 || desc_bytes > INT64_MAX/8) return -1; + if (desc_end.end_time_ns <= desc_beg.start_time_ns || + desc_end.end_time_ns - (uint64_t)desc_beg.start_time_ns > INT64_MAX) + return -1; + int64_t desc_ns = desc_end.end_time_ns - desc_beg.start_time_ns; desc_sec = desc_ns / nano_seconds_per_second; calc_bits_per_second = (desc_bytes * 8) / desc_sec; diff --git a/libavformat/mccdec.c b/libavformat/mccdec.c index 4384704f3..9d72e5545 100644 --- a/libavformat/mccdec.c +++ b/libavformat/mccdec.c @@ -313,7 +313,8 @@ static int mcc_read_header(AVFormatContext *s) if (v >= 16 && v <= 35) { int idx = v - 16; - bytestream2_put_buffer(&pb, aliases[idx].value, aliases[idx].len); + if (aliases[idx].len) + bytestream2_put_buffer(&pb, aliases[idx].value, aliases[idx].len); } else { uint8_t vv; diff --git a/libavformat/mov.c b/libavformat/mov.c index 222d79ec1..386d2f00a 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1237,15 +1237,13 @@ static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom) version = avio_r8(pb); flags = avio_rb24(pb); if (version != 0 || flags != 0) { - av_log(c->fc, AV_LOG_ERROR, - "Unsupported 'chnl' box with version %d, flags: %#x", + av_log(c->fc, AV_LOG_WARNING, + "Unsupported 'chnl' box with version %d, flags: %#x\n", version, flags); - return AVERROR_INVALIDDATA; + return 0; } - ret = ff_mov_read_chnl(c->fc, pb, st); - if (ret < 0) - return ret; + ff_mov_read_chnl(c->fc, pb, st); if (avio_tell(pb) != end) { av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n", @@ -2141,6 +2139,12 @@ static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom) return AVERROR(ENOMEM); icc_profile = sd->data; } else { + if (c->heif_icc_profile_items >= c->fc->max_streams) { + av_log(c->fc, AV_LOG_WARNING, + "HEIF ICC profile copies exceed cap %d; ignoring further items\n", + c->fc->max_streams); + return 0; + } av_freep(&item->icc_profile); icc_profile = item->icc_profile = av_malloc(atom.size - 4); if (!icc_profile) { @@ -2148,6 +2152,7 @@ static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom) return AVERROR(ENOMEM); } item->icc_profile_size = atom.size - 4; + c->heif_icc_profile_items++; } ret = ffio_read_size(pb, icc_profile, atom.size - 4); if (ret < 0) @@ -9355,6 +9360,12 @@ static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n", c->cur_item_id, width, height); + if (!width || !height || width > INT_MAX || height > INT_MAX) { + av_log(c->fc, AV_LOG_ERROR, "Invalid ispe dimensions %"PRIu32"x%"PRIu32"\n", + width, height); + return AVERROR_INVALIDDATA; + } + item = get_heif_item(c, c->cur_item_id); if (item) { item->width = width; @@ -10350,8 +10361,10 @@ static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, { MOVContext *c = s->priv_data; const HEIFItem *item = grid->item; + int64_t coded_width = 0, coded_height = 0; int64_t offset = 0, pos = avio_tell(s->pb); - int x = 0, y = 0, i = 0; + int64_t x = 0, y = 0; + int i = 0; int tile_rows, tile_cols; int flags, size; @@ -10393,9 +10406,15 @@ static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, return AVERROR_INVALIDDATA; for (int i = 0; i < tile_cols; i++) - tile_grid->coded_width += grid->tile_item_list[i]->width; + coded_width += grid->tile_item_list[i]->width; for (int i = 0; i < size; i += tile_cols) - tile_grid->coded_height += grid->tile_item_list[i]->height; + coded_height += grid->tile_item_list[i]->height; + + if (coded_width > INT_MAX || coded_height > INT_MAX) + return AVERROR_INVALIDDATA; + + tile_grid->coded_width = coded_width; + tile_grid->coded_height = coded_height; tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets)); if (!tile_grid->offsets) @@ -11483,6 +11502,12 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) #endif else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) { const uint32_t au_size = avio_rb32(sc->pb); + if (au_size > sample->size - 4) { + av_log(s, AV_LOG_ERROR, + "APV au_size %u exceeds sample body %d\n", + au_size, sample->size - 4); + return AVERROR_INVALIDDATA; + } ret = av_get_packet(sc->pb, pkt, au_size); } else ret = av_get_packet(sc->pb, pkt, sample->size); @@ -11586,6 +11611,7 @@ static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pt if (sample >= sc->sample_offsets_count) return 1; + av_assert0(sample >= 0); key_sample_dts = sti->index_entries[sample].timestamp; key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift; @@ -11629,6 +11655,8 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, next_ts = timestamp - FFMAX(sc->min_sample_duration, 1); requested_sample = av_index_search_timestamp(st, next_ts, flags); + if (requested_sample < 0) + return AVERROR_INVALIDDATA; // If we've reached a different sample trying to find a good pts to // seek to, give up searching because we'll end up seeking back to diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c index 67b22b048..8e4710fe3 100644 --- a/libavformat/mov_chan.c +++ b/libavformat/mov_chan.c @@ -375,6 +375,7 @@ static int mov_get_channel_layout(AVChannelLayout *ch_layout, uint32_t tag, uint /* find the channel layout for the specified layout tag */ layout_map = find_layout_map(tag, map); if (layout_map) { + AVChannelLayout tmp = { 0 }; int ret; int map_layout_nb_channels = tag & 0xFFFF; int nb_channels = ch_layout->nb_channels; @@ -383,19 +384,23 @@ static int mov_get_channel_layout(AVChannelLayout *ch_layout, uint32_t tag, uint if (omitted_channel_map >> map_layout_nb_channels) return AVERROR_INVALIDDATA; - av_channel_layout_uninit(ch_layout); - ret = av_channel_layout_custom_init(ch_layout, nb_channels); + ret = av_channel_layout_custom_init(&tmp, nb_channels); if (ret < 0) return ret; for (int i = 0, idx = 0; i < map_layout_nb_channels && idx < nb_channels; i++, omitted_channel_map >>= 1) { if (!(omitted_channel_map & 1)) { enum AVChannel id = layout_map[i].id; - ch_layout->u.map[idx++].id = (id != AV_CHAN_NONE ? id : AV_CHAN_UNKNOWN); + tmp.u.map[idx++].id = (id != AV_CHAN_NONE ? id : AV_CHAN_UNKNOWN); } } - return av_channel_layout_retype(ch_layout, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL); + ret = av_channel_layout_retype(&tmp, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL); + if (ret < 0) + return ret; + + av_channel_layout_uninit(ch_layout); + *ch_layout = tmp; } return 0; } @@ -543,6 +548,7 @@ int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, return 0; if (layout_tag == MOV_CH_LAYOUT_USE_DESCRIPTIONS) { + AVChannelLayout tmp = { 0 }; int nb_channels = ch_layout->nb_channels; if (!num_descr || num_descr < nb_channels) { @@ -562,8 +568,7 @@ int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, num_descr = nb_channels; } - av_channel_layout_uninit(ch_layout); - ret = av_channel_layout_custom_init(ch_layout, nb_channels); + ret = av_channel_layout_custom_init(&tmp, nb_channels); if (ret < 0) goto out; @@ -580,12 +585,15 @@ int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, avio_rl32(pb); // mCoordinates[1] avio_rl32(pb); // mCoordinates[2] size -= 20; - ch_layout->u.map[i].id = mov_get_channel_id(label); + tmp.u.map[i].id = mov_get_channel_id(label); } - ret = av_channel_layout_retype(ch_layout, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL); + ret = av_channel_layout_retype(&tmp, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL); if (ret < 0) goto out; + + av_channel_layout_uninit(ch_layout); + *ch_layout = tmp; } else if (layout_tag == MOV_CH_LAYOUT_USE_BITMAP) { if (!ch_layout->nb_channels || av_popcount(bitmap) == ch_layout->nb_channels) { if (bitmap < 0x40000) { @@ -737,11 +745,10 @@ int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st) av_log(s, AV_LOG_TRACE, "'chnl' layout %d\n", layout); if (!layout) { - AVChannelLayout *ch_layout = &st->codecpar->ch_layout; + AVChannelLayout tmp = { 0 }, *ch_layout = &st->codecpar->ch_layout; int nb_channels = ch_layout->nb_channels; - av_channel_layout_uninit(ch_layout); - ret = av_channel_layout_custom_init(ch_layout, nb_channels); + ret = av_channel_layout_custom_init(&tmp, nb_channels); if (ret < 0) return ret; @@ -762,12 +769,15 @@ int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st) channel = AV_CHAN_UNKNOWN; } - ch_layout->u.map[i].id = channel; + tmp.u.map[i].id = channel; } - ret = av_channel_layout_retype(ch_layout, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL); + ret = av_channel_layout_retype(&tmp, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL); if (ret < 0) return ret; + + av_channel_layout_uninit(ch_layout); + *ch_layout = tmp; } else { uint64_t omitted_channel_map = avio_rb64(pb); ret = ff_mov_get_channel_layout_from_config(layout, &st->codecpar->ch_layout, omitted_channel_map); diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 4b326d309..427bb88a3 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -173,6 +173,7 @@ struct MpegTSContext { /* scan context */ /** structure to keep track of Program->pids mapping */ unsigned int nb_prg; + unsigned int prg_size; ///< allocated size of prg in bytes struct Program *prg; int8_t crc_validity[NB_PID_MAX]; @@ -280,6 +281,8 @@ EXTERN const FFInputFormat ff_mpegts_demuxer; static struct Program * get_program(MpegTSContext *ts, unsigned int programid) { int i; + if (!ts) + return NULL; for (i = 0; i < ts->nb_prg; i++) { if (ts->prg[i].id == programid) { return &ts->prg[i]; @@ -316,17 +319,26 @@ static void clear_programs(MpegTSContext *ts) { av_freep(&ts->prg); ts->nb_prg = 0; + ts->prg_size = 0; } static struct Program * add_program(MpegTSContext *ts, unsigned int programid) { struct Program *p = get_program(ts, programid); + struct Program *tmp = NULL; + size_t new_prg_size; if (p) return p; - if (av_reallocp_array(&ts->prg, ts->nb_prg + 1, sizeof(*ts->prg)) < 0) { - ts->nb_prg = 0; + + if (!av_size_mult(ts->nb_prg + 1, sizeof(*ts->prg), &new_prg_size)) + tmp = av_fast_realloc(ts->prg, &ts->prg_size,new_prg_size); + if (!tmp) { + av_freep(&ts->prg); + ts->nb_prg = 0; + ts->prg_size = 0; return NULL; } + ts->prg = tmp; p = &ts->prg[ts->nb_prg]; p->id = programid; clear_program(p); @@ -1836,9 +1848,9 @@ static const uint8_t opus_channel_map[8][8] = { }; static int parse_mpeg2_extension_descriptor(AVFormatContext *fc, AVStream *st, int prg_id, - const uint8_t **pp, const uint8_t *desc_end) + const uint8_t **pp, const uint8_t *desc_end, + MpegTSContext *ts) { - MpegTSContext *ts = fc->priv_data; int ext_tag = get8(pp, desc_end); switch (ext_tag) { @@ -2438,7 +2450,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type break; case EXTENSION_DESCRIPTOR: /* descriptor extension */ { - int ret = parse_mpeg2_extension_descriptor(fc, st, prg_id, pp, desc_end); + int ret = parse_mpeg2_extension_descriptor(fc, st, prg_id, pp, desc_end, ts); if (ret < 0) return ret; diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 59b9b43a2..5d62637f5 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -1441,7 +1441,7 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int av_log(NULL, AV_LOG_WARNING, "Duplicate sony_mpeg4_extradata\n"); av_free(descriptor->extradata); descriptor->extradata_size = 0; - descriptor->extradata = av_malloc(size); + descriptor->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE); if (!descriptor->extradata) return AVERROR(ENOMEM); descriptor->extradata_size = size; diff --git a/libavformat/oggparsecelt.c b/libavformat/oggparsecelt.c index 626e1ab27..61ce8ada3 100644 --- a/libavformat/oggparsecelt.c +++ b/libavformat/oggparsecelt.c @@ -27,6 +27,9 @@ #include "internal.h" #include "oggdec.h" +/* CELT-over-Ogg streams use at most a couple of vorbiscomment "extra" headers. */ +#define CELT_MAX_EXTRA_HEADERS 16 + struct oggcelt_private { int extra_headers_left; }; @@ -62,6 +65,12 @@ static int celt_header(AVFormatContext *s, int idx) overlap = AV_RL32(p + 48); /* unused bytes per packet field skipped */ extra_headers = AV_RL32(p + 56); + if (extra_headers > CELT_MAX_EXTRA_HEADERS) { + av_log(s, AV_LOG_ERROR, + "Too many CELT extra headers (%u)\n", extra_headers); + av_free(priv); + return AVERROR_INVALIDDATA; + } st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->codec_id = AV_CODEC_ID_CELT; st->codecpar->sample_rate = sample_rate; diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c index ed81a431f..4044ad3bf 100644 --- a/libavformat/oggparsevorbis.c +++ b/libavformat/oggparsevorbis.c @@ -230,8 +230,11 @@ static int fixup_vorbis_headers(AVFormatContext *as, int i, offset, len, err; int buf_len; unsigned char *ptr; + uint64_t total_len = (uint64_t)priv->len[0] + priv->len[1] + priv->len[2]; + if (total_len + total_len / 255 + 64 > INT_MAX) + return AVERROR_INVALIDDATA; - len = priv->len[0] + priv->len[1] + priv->len[2]; + len = total_len; buf_len = len + len / 255 + 64; if (*buf) @@ -605,6 +608,13 @@ static int vorbis_packet(AVFormatContext *s, int idx) priv->comment_size = 0; av_freep(&priv->setup); priv->setup_size = 0; + + av_vorbis_parse_free(&priv->vp); + priv->vp = av_vorbis_parse_init(os->new_extradata, os->new_extradata_size); + if (!priv->vp) { + av_log(s, AV_LOG_ERROR, "Failed to re-initialize Vorbis parser\n"); + return AVERROR_INVALIDDATA; + } } return skip_packet; diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c index ec10c89fc..b32ffb0df 100644 --- a/libavformat/rtmppkt.c +++ b/libavformat/rtmppkt.c @@ -27,6 +27,8 @@ #include "flv.h" #include "url.h" +#define MAX_DEPTH 16 ///< arbitrary limit to prevent unbounded recursion + void ff_amf_write_bool(uint8_t **dst, int val) { bytestream_put_byte(dst, AMF_DATA_TYPE_BOOL); @@ -436,7 +438,7 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt) pkt->size = 0; } -static int amf_tag_skip(GetByteContext *gb) +static int amf_tag_skip(GetByteContext *gb, int depth) { AMFDataType type; unsigned nb = -1; @@ -444,6 +446,11 @@ static int amf_tag_skip(GetByteContext *gb) if (bytestream2_get_bytes_left(gb) < 1) return -1; + if (depth > MAX_DEPTH) { + av_log(NULL, AV_LOG_ERROR, "amf_tag_skip: exceeded max depth\n"); + return AVERROR_PATCHWELCOME; + } + type = bytestream2_get_byte(gb); switch (type) { case AMF_DATA_TYPE_NUMBER: @@ -479,7 +486,7 @@ static int amf_tag_skip(GetByteContext *gb) return -1; bytestream2_skip(gb, size); } - t = amf_tag_skip(gb); + t = amf_tag_skip(gb, depth + 1); if (t < 0 || bytestream2_get_bytes_left(gb) <= 0) return -1; } @@ -499,7 +506,7 @@ int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end) bytestream2_init(&gb, data, data_end - data); - ret = amf_tag_skip(&gb); + ret = amf_tag_skip(&gb, 0); if (ret < 0 || bytestream2_get_bytes_left(&gb) <= 0) return -1; av_assert0(bytestream2_tell(&gb) >= 0 && bytestream2_tell(&gb) <= data_end - data); @@ -513,7 +520,7 @@ static int amf_get_field_value2(GetByteContext *gb, int len; while (bytestream2_peek_byte(gb) != AMF_DATA_TYPE_OBJECT && bytestream2_get_bytes_left(gb) > 0) { - int ret = amf_tag_skip(gb); + int ret = amf_tag_skip(gb, 0); if (ret < 0) return -1; } @@ -550,7 +557,7 @@ static int amf_get_field_value2(GetByteContext *gb, } return 0; } - len = amf_tag_skip(gb); + len = amf_tag_skip(gb, 0); if (len < 0 || bytestream2_get_bytes_left(gb) <= 0) return -1; } @@ -593,13 +600,18 @@ static const char* rtmp_packet_type(int type) } static void amf_tag_contents(void *ctx, const uint8_t *data, - const uint8_t *data_end) + const uint8_t *data_end, int depth) { unsigned int size, nb = -1; char buf[1024]; AMFDataType type; int parse_key = 1; + if (depth > MAX_DEPTH) { + av_log(NULL, AV_LOG_ERROR, "amf_tag_contents: exceeded max depth\n"); + return; + } + if (data >= data_end) return; switch ((type = *data++)) { @@ -647,7 +659,7 @@ static void amf_tag_contents(void *ctx, const uint8_t *data, data += size; av_log(ctx, AV_LOG_DEBUG, " %s: ", buf); } - amf_tag_contents(ctx, data, data_end); + amf_tag_contents(ctx, data, data_end, depth + 1); t = ff_amf_tag_size(data, data_end); if (t < 0 || t >= data_end - data) return; @@ -670,7 +682,7 @@ void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p) uint8_t *src = p->data, *src_end = p->data + p->size; while (src < src_end) { int sz; - amf_tag_contents(ctx, src, src_end); + amf_tag_contents(ctx, src, src_end, 0); sz = ff_amf_tag_size(src, src_end); if (sz < 0) break; diff --git a/libavformat/rtpdec_av1.c b/libavformat/rtpdec_av1.c index dda17be4a..91f75326f 100644 --- a/libavformat/rtpdec_av1.c +++ b/libavformat/rtpdec_av1.c @@ -249,7 +249,7 @@ static int av1_handle_packet(AVFormatContext *ctx, PayloadContext *data, // ignore and remove OBUs according to spec if ((obu_type == AV1_OBU_TEMPORAL_DELIMITER) || (obu_type == AV1_OBU_TILE_LIST)) { - pktpos += obu_size; + buf_ptr += obu_size; rem_pkt_size -= obu_size; // TODO: This probably breaks if the OBU_TILE_LIST is fragmented // into the next RTP packet, so at least check and fail here diff --git a/libavformat/rtpenc_aac.c b/libavformat/rtpenc_aac.c index fad8ea2a5..96bdb3f70 100644 --- a/libavformat/rtpenc_aac.c +++ b/libavformat/rtpenc_aac.c @@ -34,6 +34,10 @@ void ff_rtp_send_aac(AVFormatContext *s1, const uint8_t *buff, int size) /* skip ADTS header, if present */ if ((s1->streams[0]->codecpar->extradata_size) == 0) { + if (size < 7) { + av_log(s1, AV_LOG_ERROR, "AAC packet too small for ADTS header\n"); + return; + } size -= 7; buff += 7; } diff --git a/libavformat/rtpenc_amr.c b/libavformat/rtpenc_amr.c index 8df5a3cf3..60356ac98 100644 --- a/libavformat/rtpenc_amr.c +++ b/libavformat/rtpenc_amr.c @@ -34,6 +34,10 @@ void ff_rtp_send_amr(AVFormatContext *s1, const uint8_t *buff, int size) int max_header_toc_size = 1 + s->max_frames_per_packet; uint8_t *p; int len; + int max_size = st->codecpar->codec_id == AV_CODEC_ID_AMR_NB ? 32 : 61; + + if (size < 1 || size > max_size) + return; /* Test if the packet must be sent. */ len = s->buf_ptr - s->buf; diff --git a/libavformat/rtpenc_xiph.c b/libavformat/rtpenc_xiph.c index 00c29a7d0..afea1eb79 100644 --- a/libavformat/rtpenc_xiph.c +++ b/libavformat/rtpenc_xiph.c @@ -38,6 +38,10 @@ void ff_rtp_send_xiph(AVFormatContext *s1, const uint8_t *buff, int size) uint8_t *q; max_pkt_size = s->max_payload_size - 6; // ident+frag+tdt/vdt+pkt_num+pkt_length + if (max_pkt_size <= 0) { + av_log(s1, AV_LOG_ERROR, "Max payload size too small for Xiph RTP\n"); + return; + } // set xiph data type switch (*buff) { diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c index e0bdf9d4a..4f970d4c8 100644 --- a/libavformat/rtspdec.c +++ b/libavformat/rtspdec.c @@ -191,7 +191,7 @@ static int rtsp_read_announce(AVFormatContext *s) rtsp_send_reply(s, RTSP_STATUS_SERVICE, NULL, request.seq); return AVERROR_OPTION_NOT_FOUND; } - if (request.content_length > 0) { + if (request.content_length > 0 && request.content_length <= SDP_MAX_SIZE) { sdp = av_malloc(request.content_length + 1); if (!sdp) return AVERROR(ENOMEM); diff --git a/libavformat/sctp.c b/libavformat/sctp.c index 9a6b99180..0efac12d9 100644 --- a/libavformat/sctp.c +++ b/libavformat/sctp.c @@ -309,6 +309,9 @@ static int sctp_read(URLContext *h, uint8_t *buf, int size) } if (s->max_streams) { + if (size < 2) + return AVERROR(EINVAL); + /*StreamId is introduced as a 2byte code into the stream*/ struct sctp_sndrcvinfo info = { 0 }; ret = ff_sctp_recvmsg(s->fd, buf + 2, size - 2, NULL, 0, &info, 0); diff --git a/libavformat/soxdec.c b/libavformat/soxdec.c index c710b9a15..2f16a2a43 100644 --- a/libavformat/soxdec.c +++ b/libavformat/soxdec.c @@ -88,7 +88,7 @@ static int sox_read_header(AVFormatContext *s) return AVERROR_INVALIDDATA; } - if (sample_rate <= 0 || sample_rate > INT_MAX) { + if (sample_rate <= 0 || sample_rate > INT_MAX || isnan(sample_rate)) { av_log(s, AV_LOG_ERROR, "invalid sample rate (%f)\n", sample_rate); return AVERROR_INVALIDDATA; } diff --git a/libavformat/tls_gnutls.c b/libavformat/tls_gnutls.c index 778ca9cf4..9bb272a30 100644 --- a/libavformat/tls_gnutls.c +++ b/libavformat/tls_gnutls.c @@ -31,6 +31,7 @@ #include "url.h" #include "tls.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem.h" #include "libavutil/opt.h" #include "libavutil/thread.h" #include "libavutil/random_seed.h" @@ -538,6 +539,21 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op if (!s->external_sock) { if ((ret = ff_tls_open_underlying(s, h, uri, options)) < 0) goto fail; + } else if (!s->host) { + /* With an external socket ff_tls_open_underlying() is skipped, so the + * host (used for SNI below) is never parsed. Parse it here to avoid + * passing a NULL s->host to gnutls_server_name_set(), which crashes. */ + struct addrinfo hints = { .ai_flags = AI_NUMERICHOST }, *ai = NULL; + av_url_split(NULL, 0, NULL, 0, s->underlying_host, sizeof(s->underlying_host), + NULL, NULL, 0, uri); + if (!getaddrinfo(s->underlying_host, NULL, &hints, &ai)) { + s->numerichost = 1; + freeaddrinfo(ai); + } + if (!(s->host = av_strdup(s->underlying_host))) { + ret = AVERROR(ENOMEM); + goto fail; + } } if (s->is_dtls) diff --git a/libavformat/ty.c b/libavformat/ty.c index acd5e6215..134f00d4c 100644 --- a/libavformat/ty.c +++ b/libavformat/ty.c @@ -395,12 +395,16 @@ static int demux_video(AVFormatContext *s, TyRecHdr *rec_hdr, AVPacket *pkt) int got_packet = 0; if (subrec_type != 0x02 && subrec_type != 0x0c && - subrec_type != 0x08 && rec_size > 4) { + subrec_type != 0x08 && rec_size > 7) { + /* get the PTS from this packet if it has one. * on S1, only 0x06 has PES. On S2, however, most all do. * Do NOT Pass the PES Header to the MPEG2 codec */ es_offset1 = find_es_header(ty_VideoPacket, ty->chunk + ty->cur_chunk_pos, 5); if (es_offset1 != -1) { + if (rec_size < es_offset1 + VIDEO_PTS_OFFSET + 5) + return AVERROR_INVALIDDATA; + ty->last_video_pts = ff_parse_pes_pts( ty->chunk + ty->cur_chunk_pos + es_offset1 + VIDEO_PTS_OFFSET); if (subrec_type != 0x06) { diff --git a/libavformat/version.h b/libavformat/version.h index e41362ac9..ea3d73c21 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ #include "version_major.h" #define LIBAVFORMAT_VERSION_MINOR 12 -#define LIBAVFORMAT_VERSION_MICRO 101 +#define LIBAVFORMAT_VERSION_MICRO 102 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ diff --git a/libavformat/vividas.c b/libavformat/vividas.c index 465e63dd4..5584b04c0 100644 --- a/libavformat/vividas.c +++ b/libavformat/vividas.c @@ -131,7 +131,7 @@ static void xor_block(void *p1, void *p2, unsigned size, int key, unsigned *key_ size >>= 2; while (size > 0) { - *d2 = *d1 ^ (HAVE_BIGENDIAN ? av_bswap32(k) : k); + AV_WN32(d2, AV_RN32(d1) ^ (HAVE_BIGENDIAN ? av_bswap32(k) : k)); k += key; d1++; d2++; diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c index 8ff80abc0..9673ac05f 100644 --- a/libavformat/wavdec.c +++ b/libavformat/wavdec.c @@ -131,11 +131,11 @@ static int64_t next_tag(AVIOContext *pb, uint32_t *tag, int big_endian) } /* RIFF chunks are always at even offsets relative to where they start. */ -static int64_t wav_seek_tag(WAVDemuxContext * wav, AVIOContext *s, int64_t offset, int whence) +static int64_t wav_seek_tag(WAVDemuxContext * wav, AVIOContext *s, int64_t offset) { offset += offset < INT64_MAX && offset + wav->unaligned & 1; - return avio_seek(s, offset, whence); + return avio_seek(s, offset, SEEK_SET); } /* return the size of the found tag */ @@ -144,13 +144,16 @@ static int64_t find_tag(WAVDemuxContext * wav, AVIOContext *pb, uint32_t tag1) unsigned int tag; int64_t size; + if (avio_tell(pb) + wav->unaligned & 1) + avio_skip(pb, 1); + for (;;) { if (avio_feof(pb)) return AVERROR_EOF; size = next_tag(pb, &tag, wav->rifx); if (tag == tag1) break; - wav_seek_tag(wav, pb, size, SEEK_CUR); + avio_skip(pb, size + (size & 1)); } return size; } @@ -422,7 +425,7 @@ static int wav_read_header(AVFormatContext *s) for (;;) { AVStream *vst; size = next_tag(pb, &tag, wav->rifx); - next_tag_ofs = avio_tell(pb) + size; + next_tag_ofs = avio_tell(pb) + size + (size & 1); if (avio_feof(pb)) break; @@ -454,10 +457,12 @@ static int wav_read_header(AVFormatContext *s) } if (rf64 || bw64) { - next_tag_ofs = wav->data_end = av_sat_add64(avio_tell(pb), data_size); - } else if (size != 0xFFFFFFFF) { + wav->data_end = av_sat_add64(avio_tell(pb), data_size); + next_tag_ofs = wav->data_end + (data_size & 1); + } else if (size > 0 && size != 0xFFFFFFFF) { data_size = size; - next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX; + wav->data_end = avio_tell(pb) + size; + next_tag_ofs = wav->data_end + (size & 1); } else { av_log(s, AV_LOG_WARNING, "Ignoring maximum wav data size, " "file may be invalid\n"); @@ -599,7 +604,7 @@ static int wav_read_header(AVFormatContext *s) /* seek to next tag unless we know that we'll run into EOF */ if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) || - wav_seek_tag(wav, pb, next_tag_ofs, SEEK_SET) < 0) { + wav_seek_tag(wav, pb, next_tag_ofs) < 0) { break; } } diff --git a/libavformat/whip.c b/libavformat/whip.c index c07977010..2b2859c72 100644 --- a/libavformat/whip.c +++ b/libavformat/whip.c @@ -312,6 +312,8 @@ typedef struct WHIPContext { char key_buf[MAX_CERTIFICATE_SIZE]; /* The fingerprint of certificate, used in SDP offer. */ char *dtls_fingerprint; + /* remote DTLS cert fingerprint from SDP answer (sha-256). */ + char *remote_fingerprint; /** * This represents the material used to build the SRTP master key. It is * generated by DTLS and has the following layout: @@ -952,6 +954,17 @@ static int parse_answer(AVFormatContext *s) ret = AVERROR(ENOMEM); goto end; } + } else if (av_strstart(line, "a=fingerprint:", &ptr) && !whip->remote_fingerprint) { + /* SDP a=fingerprint format is " ". Skip + * the algo token, store the hex string for post-handshake compare. */ + const char *space = strchr(ptr, ' '); + if (space) { + whip->remote_fingerprint = av_strdup(space + 1); + if (!whip->remote_fingerprint) { + ret = AVERROR(ENOMEM); + goto end; + } + } } else if (av_strstart(line, "a=candidate:", &ptr) && !whip->ice_protocol) { if (ptr && av_stristr(ptr, "host")) { /* Refer to RFC 5245 15.1 */ @@ -1001,6 +1014,17 @@ static int parse_answer(AVFormatContext *s) goto end; } + /* per RFC 8829/8842, SDP answer MUST carry a=fingerprint and that + * fingerprint MUST match the DTLS peer certificate. Without it, an + * on-path attacker can complete DTLS with an arbitrary self-signed + * certificate and the resulting SRTP session is unauthenticated. */ + if (!whip->remote_fingerprint || !strlen(whip->remote_fingerprint)) { + av_log(whip, AV_LOG_ERROR, + "No remote DTLS fingerprint in SDP answer; refusing unauthenticated session\n"); + ret = AVERROR(EINVAL); + goto end; + } + if (whip->state < WHIP_STATE_NEGOTIATED) whip->state = WHIP_STATE_NEGOTIATED; whip->whip_answer_time = av_gettime_relative(); @@ -2157,6 +2181,7 @@ static av_cold void whip_deinit(AVFormatContext *s) ffurl_closep(&whip->dtls_uc); ffurl_closep(&whip->udp); av_freep(&whip->dtls_fingerprint); + av_freep(&whip->remote_fingerprint); } static int whip_check_bitstream(AVFormatContext *s, AVStream *st, const AVPacket *pkt) diff --git a/libavutil/eval.c b/libavutil/eval.c index 56123a383..2bd07b98c 100644 --- a/libavutil/eval.c +++ b/libavutil/eval.c @@ -201,8 +201,8 @@ static double eval_expr(Parser *p, AVExpr *e) case e_func0: return e->value * e->func0(eval_expr(p, e->param[0])); case e_func1: return e->value * e->func1(p->opaque, eval_expr(p, e->param[0])); case e_func2: return e->value * e->func2(p->opaque, eval_expr(p, e->param[0]), eval_expr(p, e->param[1])); - case e_squish: return 1/(1+exp(4*eval_expr(p, e->param[0]))); - case e_gauss: { double d = eval_expr(p, e->param[0]); return exp(-d*d/2)/sqrt(2*M_PI); } + case e_squish: return e->value/(1+exp(4*eval_expr(p, e->param[0]))); + case e_gauss: { double d = eval_expr(p, e->param[0]); return e->value * exp(-d*d/2)/sqrt(2*M_PI); } case e_ld: return e->value * p->var[av_clip(eval_expr(p, e->param[0]), 0, VARS-1)]; case e_isnan: return e->value * !!isnan(eval_expr(p, e->param[0])); case e_isinf: return e->value * !!isinf(eval_expr(p, e->param[0])); @@ -233,13 +233,13 @@ static double eval_expr(Parser *p, AVExpr *e) double v0 = eval_expr(p, e->param[0]); double v1 = eval_expr(p, e->param[1]); double f = eval_expr(p, e->param[2]); - return v0 + (v1 - v0) * f; + return e->value * (v0 + (v1 - v0) * f); } case e_print: { double x = eval_expr(p, e->param[0]); int level = e->param[1] ? av_clip(eval_expr(p, e->param[1]), INT_MIN, INT_MAX) : AV_LOG_INFO; av_log(p, level, "%f\n", x); - return x; + return e->value * x; } #define COMPUTE_NEXT_RANDOM() \ diff --git a/libavutil/tests/eval.c b/libavutil/tests/eval.c index b64c6d635..1014e2b93 100644 --- a/libavutil/tests/eval.c +++ b/libavutil/tests/eval.c @@ -126,9 +126,14 @@ int main(int argc, char **argv) "root(sin(ld(0))+6+sin(ld(0)/12)-log(ld(0)), 100)", "7000000B*random(0)", "squish(2)", + "-squish(2)", "gauss(0.1)", + "-gauss(0.1)", "hypot(4,3)", "gcd(30,55)*print(min(9,1))", + "-print(42)", + "lerp(0, 100, 0.5)", + "-lerp(0, 100, 0.5)", "bitor(42, 12)", "bitand(42, 12)", "bitand(NAN, 1)", diff --git a/libavutil/version.h b/libavutil/version.h index c61f6b0e9..16335f09a 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,7 +80,7 @@ #define LIBAVUTIL_VERSION_MAJOR 60 #define LIBAVUTIL_VERSION_MINOR 26 -#define LIBAVUTIL_VERSION_MICRO 101 +#define LIBAVUTIL_VERSION_MICRO 102 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ diff --git a/libswresample/version.h b/libswresample/version.h index 403be6227..a06b24947 100644 --- a/libswresample/version.h +++ b/libswresample/version.h @@ -31,7 +31,7 @@ #include "version_major.h" #define LIBSWRESAMPLE_VERSION_MINOR 3 -#define LIBSWRESAMPLE_VERSION_MICRO 101 +#define LIBSWRESAMPLE_VERSION_MICRO 102 #define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \ LIBSWRESAMPLE_VERSION_MINOR, \ diff --git a/libswresample/x86/resample.asm b/libswresample/x86/resample.asm index 6c3dc2870..e155f171d 100644 --- a/libswresample/x86/resample.asm +++ b/libswresample/x86/resample.asm @@ -198,7 +198,8 @@ cglobal resample_common_%1, 1, 7, 2, ctx, phase_count, dst, frac, \ add fracd, dst_incr_modd packssdw m0, m0 add indexd, dst_incr_divd - movd [dstq], m0 + movd filterd, m0 + mov [dstq], filterw %else ; float/double ; horizontal sum & store %if mmsize == 32 @@ -478,7 +479,8 @@ cglobal resample_linear_%1, 1, 7, 5, ctx, min_filter_length_x4, filter2, \ paddd m0, m1 psrad m0, 15 packssdw m0, m0 - movd [dstq], m0 + movd eax, m0 + mov [dstq], ax ; note that for imul/idiv, I need to move filter to edx/eax for each: ; - 32bit: eax=r0[filter1], edx=r2[filter2] diff --git a/libswscale/aarch64/rgb2rgb_neon.S b/libswscale/aarch64/rgb2rgb_neon.S index 665aa4496..ba2f90487 100644 --- a/libswscale/aarch64/rgb2rgb_neon.S +++ b/libswscale/aarch64/rgb2rgb_neon.S @@ -795,11 +795,78 @@ w17 - set to 1 if last line has to be handled separately (odd height) add x2, x2, x7 .endm +// width is processed in whole pixel pairs; if the original width was odd this +// emits the trailing column for one line, matching the C reference. w15 holds +// the odd-width flag, the pointers are at the end of the even part of the line. +.macro write_last_odd_column src_fmt, dst_fmt, is_final_odd_line=0, y_off=0 +.ifc \dst_fmt, yuv422 + cbz w15, 0f +.ifc \src_fmt, uyvy + ldrb w12, [x3, #1] // Y = src[2w-1] + strb w12, [x0] + ldrb w12, [x3] // U = src[2w-2] + strb w12, [x1] + ldrb w12, [x3, #2] // V = src[2w] + strb w12, [x2] +.else + ldrb w12, [x3] // Y = src[2w-2] + strb w12, [x0] + ldrb w12, [x3, #1] // U = src[2w-1] + strb w12, [x1] + ldrb w12, [x3, #3] // V = src[2w+1] + strb w12, [x2] +.endif +0: +.endif +.ifc \dst_fmt, yuv420 + cbz w15, 0f +.if \is_final_odd_line + ldrb w12, [x3, #\y_off] // luma only; chroma is skipped on the odd last line + strb w12, [x0] +.else +.ifc \src_fmt, uyvy + ldrb w12, [x3, #1] // Y, top line + strb w12, [x0] + ldrb w12, [x13, #1] // Y, bottom line + strb w12, [x10] + ldrb w12, [x3] // U = (top + bottom) >> 1 + ldrb w14, [x13] + add w12, w12, w14 + lsr w12, w12, #1 + strb w12, [x1] + ldrb w12, [x3, #2] // V = (top + bottom) >> 1 + ldrb w14, [x13, #2] + add w12, w12, w14 + lsr w12, w12, #1 + strb w12, [x2] +.else + ldrb w12, [x3] // Y, top line + strb w12, [x0] + ldrb w12, [x13] // Y, bottom line + strb w12, [x10] + ldrb w12, [x3, #1] // U = (top + bottom) >> 1 + ldrb w14, [x13, #1] + add w12, w12, w14 + lsr w12, w12, #1 + strb w12, [x1] + ldrb w12, [x3, #3] // V = (top + bottom) >> 1 + ldrb w14, [x13, #3] + add w12, w12, w14 + lsr w12, w12, #1 + strb w12, [x2] +.endif +.endif +0: +.endif +.endm + .macro interleaved_yuv_to_planar src_fmt, dst_fmt function ff_\src_fmt\()to\dst_fmt\()_neon, export=1 sxtw x6, w6 sxtw x7, w7 ldrsw x8, [sp] + and w15, w4, #1 // odd width: trailing column via epilogue + bic w4, w4, #1 // process whole pixel pairs ands w11, w4, #~31 // choose between fast and slow path .ifc \dst_fmt, yuv420 @@ -825,6 +892,7 @@ function ff_\src_fmt\()to\dst_fmt\()_neon, export=1 b.ne 2b fastpath_shift_back_pointers \src_fmt, \dst_fmt, 0 fastpath_iteration \src_fmt, \dst_fmt, 0, 0 + write_last_odd_column \src_fmt, \dst_fmt subs w5, w5, #1 move_pointers_to_next_line \src_fmt, \dst_fmt b.ne 1b @@ -837,16 +905,24 @@ function ff_\src_fmt\()to\dst_fmt\()_neon, export=1 b.ne 4b fastpath_shift_back_pointers \src_fmt, \dst_fmt, 1 fastpath_iteration \src_fmt, \dst_fmt, 1, 1 +.ifc \src_fmt, uyvy + write_last_odd_column \src_fmt, \dst_fmt, 1, 1 +.else + write_last_odd_column \src_fmt, \dst_fmt, 1, 0 +.endif 3: .endif ret 6: // slow path - width is at most 31 and w9, w4, #31 + cbz w9, 9f // even part empty (orig width 0 or 1) 7: subs w9, w9, #2 slowpath_iteration \src_fmt, \dst_fmt, 0 b.ne 7b +9: + write_last_odd_column \src_fmt, \dst_fmt subs w5, w5, #1 move_pointers_to_next_line \src_fmt, \dst_fmt b.ne 6b @@ -857,10 +933,13 @@ function ff_\src_fmt\()to\dst_fmt\()_neon, export=1 .ifc \src_fmt, uyvy add x3, x3, #1 .endif + cbz w9, 10f // even part empty (orig width 0 or 1) 5: subs w9, w9, #2 slowpath_iteration \src_fmt, \dst_fmt, 1 b.ne 5b +10: + write_last_odd_column \src_fmt, \dst_fmt, 1, 0 8: .endif ret diff --git a/libswscale/output.c b/libswscale/output.c index 396380ac7..cea7fb118 100644 --- a/libswscale/output.c +++ b/libswscale/output.c @@ -1320,7 +1320,7 @@ yuv2rgba64_1_c_template(SwsInternal *c, const int32_t *buf0, } } else { const int32_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1]; - int A1 = 0xffff<<14, A2 = 0xffff<<14; + SUINT A1 = 0xffff<<14, A2 = 0xffff<<14; unsigned uvalpha1 = 4096 - uvalpha; av_assert2(uvalpha <= 4096U); @@ -1339,8 +1339,8 @@ yuv2rgba64_1_c_template(SwsInternal *c, const int32_t *buf0, Y2 += (1 << 13) - (1 << 29); if (hasAlpha) { - A1 = abuf0[i * 2 ] * (1 << 11); - A2 = abuf0[i * 2 + 1] * (1 << 11); + A1 = abuf0[i * 2 ] * (SUINT)(1 << 11); + A2 = abuf0[i * 2 + 1] * (SUINT)(1 << 11); A1 += 1 << 13; A2 += 1 << 13; @@ -1499,7 +1499,7 @@ yuv2rgba64_full_1_c_template(SwsInternal *c, const int32_t *buf0, { const int32_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0]; int i; - int A = 0xffff<<14; + SUINT A = 0xffff<<14; if (uvalpha == 0) { for (i = 0; i < dstW; i++) { @@ -1513,7 +1513,7 @@ yuv2rgba64_full_1_c_template(SwsInternal *c, const int32_t *buf0, Y += (1 << 13) - (1 << 29); if (hasAlpha) { - A = abuf0[i] * (1 << 11); + A = abuf0[i] * (SUINT)(1 << 11); A += 1 << 13; } @@ -1535,7 +1535,7 @@ yuv2rgba64_full_1_c_template(SwsInternal *c, const int32_t *buf0, } else { const int32_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1]; unsigned uvalpha1 = 4096 - uvalpha; - int A = 0xffff<<14; + SUINT A = 0xffff<<14; av_assert2(uvalpha <= 4096U); for (i = 0; i < dstW; i++) { @@ -1549,7 +1549,7 @@ yuv2rgba64_full_1_c_template(SwsInternal *c, const int32_t *buf0, Y += (1 << 13) - (1 << 29); if (hasAlpha) { - A = abuf0[i] * (1 << 11); + A = abuf0[i] * (SUINT)(1 << 11); A += 1 << 13; } diff --git a/libswscale/ppc/swscale_ppc_template.c b/libswscale/ppc/swscale_ppc_template.c index 1e0c09528..f352f75fa 100644 --- a/libswscale/ppc/swscale_ppc_template.c +++ b/libswscale/ppc/swscale_ppc_template.c @@ -90,7 +90,7 @@ static void FUNC(yuv2planeX)(const int16_t *filter, int filterSize, yuv2planeX_u(filter, filterSize, src, dest, dst_u, dither, offset, 0); - for (i = dst_u; i < dstW - 15; i += 16) + for (i = dst_u; i < dstW - 23; i += 16) FUNC(yuv2planeX_8_16)(filter, filterSize, src, dest + i, dither, offset, i); diff --git a/libswscale/ppc/swscale_vsx.c b/libswscale/ppc/swscale_vsx.c index c6948546d..21fb43092 100644 --- a/libswscale/ppc/swscale_vsx.c +++ b/libswscale/ppc/swscale_vsx.c @@ -54,7 +54,7 @@ } while (0) #define LOAD_FILTER(vf,f) {\ - vf = vec_vsx_ld(joffset, f);\ + vf = vec_splats(f[j]);\ } #define LOAD_L1(ll1,s,p){\ ll1 = vec_vsx_ld(xoffset, s);\ diff --git a/libswscale/rgb2rgb_template.c b/libswscale/rgb2rgb_template.c index 48959b6b5..1f0aef1fb 100644 --- a/libswscale/rgb2rgb_template.c +++ b/libswscale/rgb2rgb_template.c @@ -406,11 +406,11 @@ static inline void yuvPlanartoyuy2_c(const uint8_t *ysrc, const uint8_t *usrc, for (i = 0; i < chromWidth; i++) { #if HAVE_BIGENDIAN - *idst++ = (yc[0] << 24) + (uc[0] << 16) + + *idst++ = ((unsigned)yc[0] << 24) + (uc[0] << 16) + (yc[1] << 8) + (vc[0] << 0); #else *idst++ = yc[0] + (uc[0] << 8) + - (yc[1] << 16) + (vc[0] << 24); + (yc[1] << 16) + ((unsigned)vc[0] << 24); #endif yc += 2; uc++; diff --git a/libswscale/swscale.c b/libswscale/swscale.c index cd4ef9676..f2a102109 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -1004,6 +1004,16 @@ static int scale_cascaded(SwsInternal *c, 0, dstH0); if (ret < 0) return ret; + + /* The first stage assembles the full intermediate image from the input, + * one slice at a time (it is itself a regular slice-capable context). The + * second stage scales that whole intermediate to the output in one step, + * so it can only run once the entire source has been consumed. The first + * stage resets its slice direction to 0 at end of frame; until then the + * intermediate is incomplete and this call produces no output lines. */ + if (sws_internal(c->cascaded_context[0])->sliceDir != 0) + return 0; + ret = scale_internal(c->cascaded_context[1], (const uint8_t * const * )c->cascaded_tmp[0], c->cascaded_tmpStride[0], 0, dstH0, dstSlice, dstStride, dstSliceY, dstSliceH); @@ -1068,7 +1078,7 @@ static int scale_internal(SwsContext *sws, return scale_gamma(c, srcSlice, srcStride, srcSliceY, srcSliceH, dstSlice, dstStride, dstSliceY, dstSliceH); - if (c->cascaded_context[0] && srcSliceY == 0 && srcSliceH == c->cascaded_context[0]->src_h) + if (c->cascaded_context[0]) return scale_cascaded(c, srcSlice, srcStride, srcSliceY, srcSliceH, dstSlice, dstStride, dstSliceY, dstSliceH); diff --git a/libswscale/version.h b/libswscale/version.h index 0129e1685..a10801758 100644 --- a/libswscale/version.h +++ b/libswscale/version.h @@ -29,7 +29,7 @@ #include "version_major.h" #define LIBSWSCALE_VERSION_MINOR 5 -#define LIBSWSCALE_VERSION_MICRO 101 +#define LIBSWSCALE_VERSION_MICRO 102 #define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ LIBSWSCALE_VERSION_MINOR, \ diff --git a/libswscale/x86/rgb_2_rgb.asm b/libswscale/x86/rgb_2_rgb.asm index 871bb2112..120cc95c4 100644 --- a/libswscale/x86/rgb_2_rgb.asm +++ b/libswscale/x86/rgb_2_rgb.asm @@ -193,6 +193,7 @@ cglobal uyvytoyuv422, 9, 14, 8 + cpuflag(avx2) + cpuflag(avx512icl), ydst, udst, movsxdifnidn src_strideq, src_strided mov back_wq, wq + and wq, -2 ; process whole UYVY pairs; trailing odd column via epilogue mov whalfq, wq shr whalfq, 1 ; whalf = width / 2 @@ -212,7 +213,7 @@ cglobal uyvytoyuv422, 9, 14, 8 + cpuflag(avx2) + cpuflag(avx512icl), ydst, udst, ;calc scalar loop count and xq, mmsize * 2 - 1 - je .loop_simd + je .skip_tail %if mmsize == 64 shr xq, 1 @@ -292,6 +293,7 @@ cglobal uyvytoyuv422, 9, 14, 8 + cpuflag(avx2) + cpuflag(avx512icl), ydst, udst, %endif ; check if simd loop is need +.skip_tail: cmp wq, 0 jge .end_line @@ -378,6 +380,15 @@ cglobal uyvytoyuv422, 9, 14, 8 + cpuflag(avx2) + cpuflag(avx512icl), ydst, udst, jl .loop_simd .end_line: + test back_wq, 1 + jz .skip_last + mov tmpb, [srcq + 1] + mov [ydstq], tmpb + mov tmpb, [srcq + 0] + mov [udstq], tmpb + mov tmpb, [srcq + 2] + mov [vdstq], tmpb + .skip_last: add srcq, src_strideq add ydstq, lum_strideq add udstq, chrom_strideq @@ -385,6 +396,7 @@ cglobal uyvytoyuv422, 9, 14, 8 + cpuflag(avx2) + cpuflag(avx512icl), ydst, udst, ;restore initial state of line variable mov wq, back_wq + and wq, -2 mov xq, wq mov whalfq, wq shr whalfq, 1 ; whalf = width / 2 diff --git a/msys2/PKGBUILD/30-mingw-w64-harfbuzz/PKGBUILD b/msys2/PKGBUILD/30-mingw-w64-harfbuzz/PKGBUILD index fea46366b..e0a32dd0a 100644 --- a/msys2/PKGBUILD/30-mingw-w64-harfbuzz/PKGBUILD +++ b/msys2/PKGBUILD/30-mingw-w64-harfbuzz/PKGBUILD @@ -4,7 +4,7 @@ _realname=harfbuzz pkgbase=mingw-w64-jellyfin-${_realname} pkgname=("${MINGW_PACKAGE_PREFIX}-jellyfin-${_realname}") -pkgver=14.2.0 +pkgver=14.2.1 pkgrel=1 pkgdesc="OpenType text shaping engine" arch=('any') @@ -29,7 +29,7 @@ checkdepends=("${MINGW_PACKAGE_PREFIX}-python-fonttools" source=("https://github.com/harfbuzz/harfbuzz/releases/download/${pkgver}/harfbuzz-${pkgver}.tar.xz" "001-fix-build-with-chafa.patch" "002-make-library-type-in-cmake-config-unknown.patch") -sha256sums=('94017020f96d025bb66ae91574e4cf334bcad23e8175a8a40565b3721bc2eaff' +sha256sums=('a54a5d8e9380a41fbb762ce367bcbf7704792dfca0d93f1bbca86c5a57902e0e' '26b37a1ca9872973905ecb96bcbe3f054472252320956faa74428206900d360e' '6ce1063f2ac77db0b4705153031e2c6ba8d7a65a04eb759fe4178e9445406ddb') noextract=("harfbuzz-${pkgver}.tar.xz") diff --git a/msys2/PKGBUILD/40-mingw-w64-libass/PKGBUILD b/msys2/PKGBUILD/40-mingw-w64-libass/PKGBUILD index 1b1c58a46..e8756d13e 100644 --- a/msys2/PKGBUILD/40-mingw-w64-libass/PKGBUILD +++ b/msys2/PKGBUILD/40-mingw-w64-libass/PKGBUILD @@ -3,7 +3,7 @@ _realname=libass pkgbase=mingw-w64-jellyfin-${_realname} pkgname="${MINGW_PACKAGE_PREFIX}-${_realname}" -pkgver=0.17.4 +pkgver=0.17.5 pkgrel=1 pkgdesc="A portable library for SSA/ASS subtitles rendering (mingw-w64)" arch=('any') @@ -13,15 +13,17 @@ msys2_references=( "cpe: cpe:/a:libass_project:libass" ) license=('spdx:ISC') -makedepends=("${MINGW_PACKAGE_PREFIX}-autotools" - "${MINGW_PACKAGE_PREFIX}-cc" - $( [[ "${CARCH}" != "i686" \ - && "${CARCH}" != "x86_64" ]] \ - || echo "${MINGW_PACKAGE_PREFIX}-nasm" )) +makedepends=( + "${MINGW_PACKAGE_PREFIX}-cc" + "${MINGW_PACKAGE_PREFIX}-meson" + "${MINGW_PACKAGE_PREFIX}-ninja" + $([[ "${MSYSTEM}" == "CLANGARM64" ]] || echo "${MINGW_PACKAGE_PREFIX}-nasm") +) depends=("${MINGW_PACKAGE_PREFIX}-jellyfin-fribidi" "${MINGW_PACKAGE_PREFIX}-jellyfin-fontconfig" "${MINGW_PACKAGE_PREFIX}-jellyfin-freetype" "${MINGW_PACKAGE_PREFIX}-jellyfin-libunibreak" + "${MINGW_PACKAGE_PREFIX}-jellyfin-libiconv" "${MINGW_PACKAGE_PREFIX}-jellyfin-harfbuzz") source=(https://github.com/libass/${_realname}/releases/download/${pkgver}/${_realname}-${pkgver}.tar.xz fix-strndup-mingw.patch) @@ -34,34 +36,33 @@ export FF_MINGW_PREFIX="${MINGW_TOOLCHAIN_PREFIX}/ffbuild" prepare() { cd "${srcdir}/${_realname}-${pkgver}" patch -p1 -i "${srcdir}/fix-strndup-mingw.patch" - # autoreconf to get updated libtool for clang - autoreconf -fiv } build() { - [[ -d "${srcdir}/build-${MSYSTEM}-static" ]] && rm -rf "${srcdir}/build-${MSYSTEM}-static" - mkdir -p "${srcdir}/build-${MSYSTEM}-static" && cd "${srcdir}/build-${MSYSTEM}-static" - export PKG_CONFIG_PATH="${FF_MINGW_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}" - CPPFLAGS+=" -DFRIBIDI_LIB_STATIC" \ - ../${_realname}-${pkgver}/configure \ - --prefix=${FF_MINGW_PREFIX} \ - --build=${MINGW_CHOST} \ - --host=${MINGW_CHOST} \ - --target=${MINGW_CHOST} \ - --disable-shared \ - --enable-static \ - --enable-directwrite \ - --enable-libunibreak \ - --with-pic \ - $( [[ "${CARCH}" != "i686" \ - && "${CARCH}" != "x86_64" ]] \ - || echo "--enable-asm") - make + CPPFLAGS+=" -DFRIBIDI_LIB_STATIC" \ + MSYS2_ARG_CONV_EXCL="--prefix=" \ + ${MINGW_TOOLCHAIN_PREFIX}/bin/meson setup \ + --prefix="${FF_MINGW_PREFIX}" \ + --wrap-mode=nodownload \ + --buildtype=plain \ + --default-library=static \ + -Dtest=disabled \ + -Dcompare=disabled \ + -Dprofile=disabled \ + -Dfuzz=disabled \ + -Dcheckasm=disabled \ + -Dfontconfig=enabled \ + -Ddirectwrite=enabled \ + -Dasm=enabled \ + -Dlibunibreak=enabled \ + "build-${MSYSTEM}-static" \ + "${_realname}-${pkgver}" + + ${MINGW_TOOLCHAIN_PREFIX}/bin/meson compile -C "build-${MSYSTEM}-static" } package() { - cd "${srcdir}/build-${MSYSTEM}-static" - make DESTDIR="${pkgdir}" install + ${MINGW_TOOLCHAIN_PREFIX}/bin/meson install -C "build-${MSYSTEM}-static" --destdir "${pkgdir}" } diff --git a/msys2/PKGBUILD/40-mingw-w64-libopenmpt/PKGBUILD b/msys2/PKGBUILD/40-mingw-w64-libopenmpt/PKGBUILD index 88fda3f94..a0eb5a186 100644 --- a/msys2/PKGBUILD/40-mingw-w64-libopenmpt/PKGBUILD +++ b/msys2/PKGBUILD/40-mingw-w64-libopenmpt/PKGBUILD @@ -3,7 +3,7 @@ _realname=libopenmpt pkgbase=mingw-w64-jellyfin-${_realname} pkgname=("${MINGW_PACKAGE_PREFIX}-jellyfin-${_realname}") -pkgver=0.8.6 +pkgver=0.8.7 pkgrel=1 pkgdesc="A cross-platform C++ and C library to decode tracked music files (modules) into a raw PCM audio stream (mingw-w64)" arch=('any') @@ -20,7 +20,7 @@ depends=("${MINGW_PACKAGE_PREFIX}-jellyfin-zlib" makedepends=("${MINGW_PACKAGE_PREFIX}-cc" "${MINGW_PACKAGE_PREFIX}-autotools") source=("https://lib.openmpt.org/files/${_realname}/src/${_realname}-${pkgver}+release.autotools.tar.gz") -sha256sums=('caa2fa959e389f4374d9e2df3af5c633452c12dd80442cba2e89cb7ff2b93c5b') +sha256sums=('SKIP') export MINGW_TOOLCHAIN_PREFIX="${MINGW_PREFIX}" export FF_MINGW_PREFIX="${MINGW_TOOLCHAIN_PREFIX}/ffbuild" diff --git a/msys2/PKGBUILD/50-mingw-w64-amf-headers/PKGBUILD b/msys2/PKGBUILD/50-mingw-w64-amf-headers/PKGBUILD index 7cf400e49..e48f846a2 100644 --- a/msys2/PKGBUILD/50-mingw-w64-amf-headers/PKGBUILD +++ b/msys2/PKGBUILD/50-mingw-w64-amf-headers/PKGBUILD @@ -3,7 +3,7 @@ _realname=amf-headers pkgbase=mingw-w64-jellyfin-${_realname} pkgname="${MINGW_PACKAGE_PREFIX}-jellyfin-${_realname}" -pkgver=1.5.0 +pkgver=1.5.2 pkgrel=1 pkgdesc='Header files for AMD Advanced Media Framework' arch=('any') diff --git a/msys2/PKGBUILD/50-mingw-w64-libvpl/PKGBUILD b/msys2/PKGBUILD/50-mingw-w64-libvpl/PKGBUILD index 01628bc94..1b3a808bb 100644 --- a/msys2/PKGBUILD/50-mingw-w64-libvpl/PKGBUILD +++ b/msys2/PKGBUILD/50-mingw-w64-libvpl/PKGBUILD @@ -3,7 +3,7 @@ _realname=libvpl pkgbase=mingw-w64-jellyfin-${_realname} pkgname=("${MINGW_PACKAGE_PREFIX}-jellyfin-${_realname}") -pkgver=2.16.0 +pkgver=2.17.0 pkgrel=1 pkgdesc="Intel Video Processing Library (mingw-w64)" arch=('any') @@ -66,6 +66,7 @@ build() { "${extra_config[@]}" \ -DBUILD_SHARED_LIBS=OFF \ -DINSTALL_{DEV,LIB}=ON \ + -DINSTALL_EXAMPLES=OFF \ -DBUILD_{TESTS,EXAMPLES,EXPERIMENTAL}=OFF \ ../libvpl-${pkgver} @@ -76,8 +77,6 @@ package() { cd "${srcdir}/build-${MSYSTEM}-static" DESTDIR="${pkgdir}" "${MINGW_TOOLCHAIN_PREFIX}"/bin/cmake.exe --install . - rm -r "${pkgdir}${FF_MINGW_PREFIX}/share/vpl/examples" - install -Dm644 "${srcdir}/libvpl-${pkgver}/LICENSE" "${pkgdir}${FF_MINGW_PREFIX}/share/licenses/${_realname}/LICENSE" echo "Libs.private: -lstdc++" >> "${pkgdir}"${FF_MINGW_PREFIX}/lib/pkgconfig/vpl.pc diff --git a/msys2/PKGBUILD/50-mingw-w64-shaderc/PKGBUILD b/msys2/PKGBUILD/50-mingw-w64-shaderc/PKGBUILD index 621c891e9..ffe0e40ce 100644 --- a/msys2/PKGBUILD/50-mingw-w64-shaderc/PKGBUILD +++ b/msys2/PKGBUILD/50-mingw-w64-shaderc/PKGBUILD @@ -3,7 +3,7 @@ _realname=shaderc pkgbase=mingw-w64-jellyfin-${_realname} pkgname=("${MINGW_PACKAGE_PREFIX}-jellyfin-${_realname}") -pkgver=2026.1 +pkgver=2026.2 pkgrel=1 pkgdesc="Collection of tools, libraries and tests for shader compilation (mingw-w64)" arch=('any') diff --git a/msys2/PKGBUILD/50-mingw-w64-spirv-cross/PKGBUILD b/msys2/PKGBUILD/50-mingw-w64-spirv-cross/PKGBUILD index d96bf14cd..a3672433d 100644 --- a/msys2/PKGBUILD/50-mingw-w64-spirv-cross/PKGBUILD +++ b/msys2/PKGBUILD/50-mingw-w64-spirv-cross/PKGBUILD @@ -4,7 +4,7 @@ _realname=spirv-cross pkgbase=mingw-w64-jellyfin-${_realname} pkgname="${MINGW_PACKAGE_PREFIX}-jellyfin-${_realname}" epoch=1 -pkgver=1.4.341.0 +pkgver=1.4.350.1 pkgrel=1 pkgdesc="A tool and library for parsing and converting SPIR-V to other shader languages (mingw-w64)" arch=('any') diff --git a/msys2/PKGBUILD/50-mingw-w64-vulkan-headers/PKGBUILD b/msys2/PKGBUILD/50-mingw-w64-vulkan-headers/PKGBUILD index d77531fb2..4bfb8b6a6 100644 --- a/msys2/PKGBUILD/50-mingw-w64-vulkan-headers/PKGBUILD +++ b/msys2/PKGBUILD/50-mingw-w64-vulkan-headers/PKGBUILD @@ -4,7 +4,7 @@ _realname=Vulkan-Headers pkgbase=mingw-w64-jellyfin-vulkan-headers pkgname=("${MINGW_PACKAGE_PREFIX}-jellyfin-vulkan-headers") -pkgver=1.4.349 +pkgver=1.4.355 pkgrel=1 epoch=1 pkgdesc='Vulkan header files (mingw-w64)' diff --git a/msys2/PKGBUILD/50-mingw-w64-vulkan-shim-loader/PKGBUILD b/msys2/PKGBUILD/50-mingw-w64-vulkan-shim-loader/PKGBUILD index b83e85d6d..f54204192 100644 --- a/msys2/PKGBUILD/50-mingw-w64-vulkan-shim-loader/PKGBUILD +++ b/msys2/PKGBUILD/50-mingw-w64-vulkan-shim-loader/PKGBUILD @@ -2,7 +2,7 @@ _realname=Vulkan-Shim-Loader pkgbase=mingw-w64-jellyfin-vulkan-shim-loader pkgname=("${MINGW_PACKAGE_PREFIX}-jellyfin-vulkan-shim-loader") provides=("${MINGW_PACKAGE_PREFIX}-jellyfin-vulkan") -pkgver=1.4.349 +pkgver=1.4.355 pkgrel=1 epoch=1 pkgdesc='Vulkan shim loader (mingw-w64)' diff --git a/msys2/PKGBUILD/55-mingw-w64-spirv-headers/PKGBUILD b/msys2/PKGBUILD/55-mingw-w64-spirv-headers/PKGBUILD index 62d05e22f..da148e44d 100644 --- a/msys2/PKGBUILD/55-mingw-w64-spirv-headers/PKGBUILD +++ b/msys2/PKGBUILD/55-mingw-w64-spirv-headers/PKGBUILD @@ -5,7 +5,7 @@ _realname=spirv-headers pkgbase=mingw-w64-jellyfin-${_realname} pkgname="${MINGW_PACKAGE_PREFIX}-jellyfin-${_realname}" epoch=2 -pkgver=1.4.341.0 +pkgver=1.4.350.1 pkgrel=1 pkgdesc='Machine-readable files for the SPIR-V Registry (mingw-w64)' arch=('any') diff --git a/tests/checkasm/crc.c b/tests/checkasm/crc.c index 60d9ef601..32a1aae3a 100644 --- a/tests/checkasm/crc.c +++ b/tests/checkasm/crc.c @@ -44,17 +44,19 @@ static void check_crc(const AVCRC *table_new, const char *name, unsigned idx) return; DECLARE_ALIGNED(4, uint8_t, buf)[8192]; - size_t offset = rnd() & 31; + static size_t offsets[AV_CRC_MAX + 1]; static size_t sizes[AV_CRC_MAX + 1]; static unsigned sizes_initialized = 0; uint32_t prev_crc = rnd(); if (!(sizes_initialized & (1 << idx))) { sizes_initialized |= 1 << idx; - sizes[idx] = rnd() % (sizeof(buf) - 1 - offset); + offsets[idx] = rnd() & 31; + sizes[idx] = rnd() % (sizeof(buf) - 1 - offsets[idx]); } size_t size = sizes[idx]; + size_t offset = offsets[idx]; for (size_t j = 0; j < sizeof(buf); j += 4) AV_WN32A(buf + j, rnd()); diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index 07b8632c6..2ec4c5f49 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -51,6 +51,12 @@ fate-filter-mcdeint-medium: CMD = framecrc -flags bitexact -idct simple -i $(TAR FATE_FILTER_SAMPLES-$(call FILTERDEMDEC, MCDEINT, MPEGTS, MPEG2VIDEO, SNOW_ENCODER) += $(FATE_MCDEINT) +FATE_FILTER-$(call FILTERFRAMECRC, MCDEINT TESTSRC, SNOW_ENCODER) += fate-filter-mcdeint-slow-edge +fate-filter-mcdeint-slow-edge: CMD = framecrc -auto_conversion_filters -flags bitexact -lavfi testsrc=s=5x32:r=25:d=1,mcdeint=mode=slow -frames:v 3 + +FATE_FILTER-$(call FILTERFRAMECRC, MCDEINT TESTSRC, SNOW_ENCODER) += fate-filter-mcdeint-slow +fate-filter-mcdeint-slow: CMD = framecrc -auto_conversion_filters -flags bitexact -lavfi testsrc=s=128x2:r=25:d=1,mcdeint=mode=slow -frames:v 3 + FATE_FILTER_SAMPLES-$(call FILTERDEMDEC, CODECVIEW, RM, RV40) += fate-filter-codecview-mvs fate-filter-codecview-mvs: CMD = framecrc -flags2 +export_mvs -i $(TARGET_SAMPLES)/real/spygames-2MB.rmvb -vf codecview=mv=pf+bf+bb -frames:v 60 -an diff --git a/tests/ref/fate/eval b/tests/ref/fate/eval index 441f9846c..196c1b5c8 100644 --- a/tests/ref/fate/eval +++ b/tests/ref/fate/eval @@ -262,15 +262,30 @@ Evaluating '7000000B*random(0)' Evaluating 'squish(2)' 'squish(2)' -> 0.000335 +Evaluating '-squish(2)' +'-squish(2)' -> -0.000335 + Evaluating 'gauss(0.1)' 'gauss(0.1)' -> 0.396953 +Evaluating '-gauss(0.1)' +'-gauss(0.1)' -> -0.396953 + Evaluating 'hypot(4,3)' 'hypot(4,3)' -> 5.000000 Evaluating 'gcd(30,55)*print(min(9,1))' 'gcd(30,55)*print(min(9,1))' -> 5.000000 +Evaluating '-print(42)' +'-print(42)' -> -42.000000 + +Evaluating 'lerp(0, 100, 0.5)' +'lerp(0, 100, 0.5)' -> 50.000000 + +Evaluating '-lerp(0, 100, 0.5)' +'-lerp(0, 100, 0.5)' -> -50.000000 + Evaluating 'bitor(42, 12)' 'bitor(42, 12)' -> 46.000000 diff --git a/tests/ref/fate/filter-mcdeint-slow b/tests/ref/fate/filter-mcdeint-slow new file mode 100644 index 000000000..0888d4480 --- /dev/null +++ b/tests/ref/fate/filter-mcdeint-slow @@ -0,0 +1,8 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x2 +#sar 0: 1/1 +0, 0, 0, 1, 768, 0x6d637c68 +0, 1, 1, 1, 768, 0x07867cb0 +0, 2, 2, 1, 768, 0xa1ef7d04 diff --git a/tests/ref/fate/filter-mcdeint-slow-edge b/tests/ref/fate/filter-mcdeint-slow-edge new file mode 100644 index 000000000..c6411b3ad --- /dev/null +++ b/tests/ref/fate/filter-mcdeint-slow-edge @@ -0,0 +1,8 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 5x32 +#sar 0: 1/1 +0, 0, 0, 1, 480, 0xe8a1f302 +0, 1, 1, 1, 480, 0x0789f31c +0, 2, 2, 1, 480, 0x113af329 diff --git a/tests/tiny_ssim.c b/tests/tiny_ssim.c index 974065228..8472fc3b1 100644 --- a/tests/tiny_ssim.c +++ b/tests/tiny_ssim.c @@ -79,11 +79,11 @@ static float ssim_end1( int s1, int s2, int ss, int s12 ) * Maximum value for 9-bit is: ss*64 = (2^9-1)^2*16*4*64 = 1069551616, which will not overflow. */ #if BIT_DEPTH > 9 typedef float type; - static const float ssim_c1 = .01*.01*PIXEL_MAX*PIXEL_MAX*64; + static const float ssim_c1 = .01*.01*PIXEL_MAX*PIXEL_MAX*64*64; static const float ssim_c2 = .03*.03*PIXEL_MAX*PIXEL_MAX*64*63; #else typedef int type; - static const int ssim_c1 = (int)(.01*.01*PIXEL_MAX*PIXEL_MAX*64 + .5); + static const int ssim_c1 = (int)(.01*.01*PIXEL_MAX*PIXEL_MAX*64*64 + .5); static const int ssim_c2 = (int)(.03*.03*PIXEL_MAX*PIXEL_MAX*64*63 + .5); #endif type fs1 = s1; diff --git a/tools/target_dem_fuzzer.c b/tools/target_dem_fuzzer.c index e169438ce..aefec2ec0 100644 --- a/tools/target_dem_fuzzer.c +++ b/tools/target_dem_fuzzer.c @@ -182,8 +182,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { error("Failed to allocate pkt"); io_buffer = av_malloc(io_buffer_size); - if (!io_buffer) - error("Failed to allocate io_buffer"); + if (!io_buffer) { + avformat_free_context(avfmt); + av_packet_free(&pkt); + return 0; + } opaque.filesize = filesize; opaque.pos = 0; diff --git a/tools/zmqsend.c b/tools/zmqsend.c index dc5d426cc..17a6194b2 100644 --- a/tools/zmqsend.c +++ b/tools/zmqsend.c @@ -55,7 +55,7 @@ static void usage(void) int main(int argc, char **argv) { AVBPrint src; - char *src_buf, *recv_buf; + char *src_buf = NULL, *recv_buf; int c; int recv_buf_size, ret = 0; void *zmq_ctx, *socket; @@ -165,6 +165,7 @@ int main(int argc, char **argv) av_free(recv_buf); end: + av_freep(&src_buf); zmq_close(socket); zmq_ctx_destroy(zmq_ctx); return ret;