diff -Nru ffmpeg-4.4.1/Changelog ffmpeg-4.4.2/Changelog --- ffmpeg-4.4.1/Changelog 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/Changelog 2022-04-14 21:13:48.000000000 +0100 @@ -1,6 +1,121 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. +version 4.4.2: +- fate: update reference files after the recent dash manifest muxer changes +- avformat/webmdashenc: fix on-demand profile string +- Update for FFmpeg 4.4.2 +- avcodec/exr: Avoid signed overflow in displayWindow +- avcodec/diracdec: avoid signed integer overflow in global mv +- avcodec/takdsp: Fix integer overflow in decorrelate_sf() +- avcodec/apedec: fix a integer overflow in long_filter_high_3800() +- avfilter/vf_subtitles: pass storage size to libass +- avformat/aqtitledec: Skip unrepresentable durations +- avformat/cafdec: Do not store empty keys in read_info_chunk() +- avformat/mxfdec: Do not clear array in mxf_read_strong_ref_array() before writing +- avformat/mxfdec: Check for avio_read() failure in mxf_read_strong_ref_array() +- avformat/mxfdec: Check count in mxf_read_strong_ref_array() +- avformat/hls: Check target_duration +- avcodec/pixlet: Avoid signed integer overflow in scaling in filterfn() +- avformat/matroskadec: Check pre_ns +- avcodec/sonic: Use unsigned for predictor_k to avoid undefined behavior +- avcodec/libuavs3d: Check ff_set_dimensions() for failure +- avcodec/mjpegbdec: Set buf_size +- avformat/matroskadec: Use rounded down duration in get_cue_desc() check +- avcodec/argo: Check packet size +- avcodec/g729_parser: Check channels +- avformat/avidec: Check height +- avformat/rmdec: Better duplicate tags check +- avformat/mov: Disallow empty sidx +- avformat/argo_asf: Fix order of operations in error check in argo_asf_write_trailer() +- avformat/matroskadec: Check duration +- avformat/mov: Corner case encryption error cleanup in mov_read_senc() +- avcodec/jpeglsdec: Fix if( code style +- avcodec/jpeglsdec: Check get_ur_golomb_jpegls() for error +- avcodec/motion_est: fix indention of ff_get_best_fcode() +- avcodec/motion_est: Fix xy indexing on range violation in ff_get_best_fcode() +- avformat/hls: Use unsigned for iv computation +- avcodec/jpeglsdec: Increase range for N in ls_get_code_runterm() by using unsigned +- avformat/matroskadec: Check desc_bytes +- avformat/utils: Fix invalid NULL pointer operation in ff_parse_key_value() +- avformat/matroskadec: Fix infinite loop with bz decompression +- avformat/mov: Check size before subtraction +- avcodec/cfhd: Avoid signed integer overflow in coeff +- avcodec/apedec: Fix integer overflows in predictor_update_3930() +- avcodec/apedec: fix integer overflow in 8bit samples +- avformat/flvdec: timestamps cannot use the full int64 range +- avcodec/tiff: Remove messing with jpeg context +- avcodec/tiff: Use ff_set_dimensions() for setting up mjpeg context dimensions +- avcodec/tiff: Pass max_pixels to mjpeg context +- avcodec/vqavideo: reset accounting on error +- avcodec/alacdsp: fix integer overflow in decorrelate_stereo() +- avformat/4xm: Check for duplicate track ids +- avformat/4xm: Consider max_streams on reallocating tracks array +- avformat/mov: Check next offset in mov_read_dref() +- avformat/vivo: Favor setting fps from explicit fractions +- avformat/vivo: Do not use the general expression evaluator for parsing a floating point value +- avformat/mxfdec: Check for duplicate mxf_read_index_entry_array() +- avcodec/apedec: Change avg to uint32_t +- avformat/mxfdec: Check component_depth in mxf_get_color_range() +- avformat/mov: Disallow duplicate smdm +- avformat/mov: Check for EOF in mov_read_glbl() +- avcodec/vp3: Check version in all cases when VP4 code is not built +- avformat/mov: Check channels for mov_parse_stsd_audio() +- avformat/avidec: Check read_odml_index() for failure +- avformat/aiffdec: Use av_rescale() for bitrate +- avformat/aiffdec: sanity check block_align +- avformat/aiffdec: Check sample_rate +- avcodec/libdav1d: free the Dav1dData packet on dav1d_send_data() failure +- avcodec/zmbvenc: Fix memleak upon init error +- avcodec/dnxhdenc: Fix segfault when using too many slice threads +- avcodec/wma(dec|enc): Fix memleaks upon allocation error +- avfilter/avfilter: Actually error out on init error +- avcodec/opus_silk: Remove wrong size information in function declaration +- avformat/omadec: Don't output uninitialized values +- avformat/jacosubenc: Fix writing extradata +- avformat/cafenc: Fix memleak when trailer is never written +- avformat/cafenc: Don't segfault upon allocation error +- avformat/cafenc: Fix potential integer overflow +- avformat/movenc: Limit ism_lookahead to a sane value +- avutil/utils: Remove racy check from avutil_version() +- avformat/sccdec: Don't use uninitialized data, fix crash, simplify logic +- avformat/subtitles: Honour ff_subtitles_read_line() documentation +- avformat/tee: Fix leak of FIFO-options dictionary +- avformat/tee: Fix leak of strings +- avcodec/rasc: Fix potential use of uninitialized value +- avfilter/vf_w3fdif: Fix segfault on allocation error +- avfilter/af_surround: Fix memleaks upon allocation error +- avfilter/af_vibrato: Fix segfault upon allocation error +- avfilter/aeval: Fix leak of expressions upon reallocation error +- avdevice/xv: Increase array size +- avfilter/asrc_flite: Fix use-after-frees +- avfilter/asrc_flite: Don't segfault when using list_voices option +- Revert "avfilter/vf_idet: reduce noisyness if the filter has been auto inserted" +- avformat/matroskadec: Don't unnecessarily reduce aspect ratio +- avcodec/h263: Fix global-buffer-overflow with noout flag2 set +- avcodec/vaapi_encode: Fix segfault upon closing uninitialized encoder +- avcodec/movtextenc: Fix infinite loop due to variable truncation +- avcodec/libopenh264dec: Increase array sizes, fix stack-buffer overread +- avcodec/libkvazaar: Increase array size +- avformat/aadec: Don't use the same loop counter in inner and outer loop +- avformat/moflex: Don't use uninitialized timebase for data stream +- lavf/udp: do not return an uninitialized value from udp_open() +- avcodec/nvenc: zero-initialize NV_ENC_REGISTER_RESOURCE struct +- configure: Add missing libshine->mpegaudioheader dependency +- avcodec/Makefile: Add missing entry for ADPCM_IMA_AMV_ENCODER +- avcodec/Makefile: Only compile nvenc.o if needed +- avcodec/av1_vaapi: improve decode quality +- avcodec/av1_vaapi: enable segmentation features +- avcodec/av1_vaapi: setting 2 output surface for film grain +- avcodec/vaapi: increase av1 decode pool size +- avcodec/dxva2_av1: fix global motion params +- avcodec/av1_vaapi: add gm params valid check +- avcodec/av1dec: support setup shear process +- avcodec/av1: extend some definitions in spec section 3 +- cbs_av1: fix incorrect data type +- avcodec/libdav1d: let libdav1d choose optimal max frame delay +- avcodec/libdav1d: pass auto threads value to libdav1d + version 4.4.1: - avcodec/flac_parser: Consider AV_INPUT_BUFFER_PADDING_SIZE - avcodec/ttadsp: Fix integer overflows in tta_filter_process_c() diff -Nru ffmpeg-4.4.1/configure ffmpeg-4.4.2/configure --- ffmpeg-4.4.1/configure 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/configure 2022-04-14 21:13:38.000000000 +0100 @@ -3268,7 +3268,7 @@ librav1e_encoder_select="extract_extradata_bsf" librsvg_decoder_deps="librsvg" libshine_encoder_deps="libshine" -libshine_encoder_select="audio_frame_queue" +libshine_encoder_select="audio_frame_queue mpegaudioheader" libspeex_decoder_deps="libspeex" libspeex_encoder_deps="libspeex" libspeex_encoder_select="audio_frame_queue" diff -Nru ffmpeg-4.4.1/debian/changelog ffmpeg-4.4.2/debian/changelog --- ffmpeg-4.4.1/debian/changelog 2022-03-13 08:00:39.000000000 +0000 +++ ffmpeg-4.4.2/debian/changelog 2022-05-19 07:10:36.000000000 +0100 @@ -1,3 +1,10 @@ +ffmpeg (7:4.4.2-0ubuntu0.22.04.1) jammy-security; urgency=medium + + * SECURITY UPDATE: New upstream bugfix release. + - Fixes security issues without a CVE number (see DSA-5124-1 and DSA-5126-1). + + -- Luís Infante da Câmara Thu, 19 May 2022 07:10:36 +0100 + ffmpeg (7:4.4.1-3ubuntu5) jammy; urgency=medium * Rebuild against new old libsndio7.0. diff -Nru ffmpeg-4.4.1/doc/Doxyfile ffmpeg-4.4.2/doc/Doxyfile --- ffmpeg-4.4.1/doc/Doxyfile 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/doc/Doxyfile 2022-04-14 21:13:48.000000000 +0100 @@ -38,7 +38,7 @@ # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 4.4.1 +PROJECT_NUMBER = 4.4.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 -Nru ffmpeg-4.4.1/libavcodec/alacdsp.c ffmpeg-4.4.2/libavcodec/alacdsp.c --- ffmpeg-4.4.1/libavcodec/alacdsp.c 2021-10-21 18:06:35.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/alacdsp.c 2022-04-14 21:13:48.000000000 +0100 @@ -34,7 +34,7 @@ a = buffer[0][i]; b = buffer[1][i]; - a -= (b * decorr_left_weight) >> decorr_shift; + a -= (int)(b * (unsigned)decorr_left_weight) >> decorr_shift; b += a; buffer[0][i] = b; diff -Nru ffmpeg-4.4.1/libavcodec/apedec.c ffmpeg-4.4.2/libavcodec/apedec.c --- ffmpeg-4.4.1/libavcodec/apedec.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/apedec.c 2022-04-14 21:13:48.000000000 +0100 @@ -102,7 +102,7 @@ int16_t *historybuffer; ///< filter memory int16_t *delay; ///< filtered values - int avg; + uint32_t avg; } APEFilter; typedef struct APERice { @@ -955,7 +955,7 @@ dotprod += delay[j] * (unsigned)coeffs[j]; coeffs[j] += ((delay[j] >> 31) | 1) * sign; } - buffer[i] -= dotprod >> shift; + buffer[i] -= (unsigned)(dotprod >> shift); for (j = 0; j < order - 1; j++) delay[j] = delay[j + 1]; delay[order - 1] = buffer[i]; @@ -1088,13 +1088,13 @@ const int delayA) { int32_t predictionA, sign; - int32_t d0, d1, d2, d3; + uint32_t d0, d1, d2, d3; p->buf[delayA] = p->lastA[filter]; d0 = p->buf[delayA ]; - d1 = p->buf[delayA ] - p->buf[delayA - 1]; - d2 = p->buf[delayA - 1] - p->buf[delayA - 2]; - d3 = p->buf[delayA - 2] - p->buf[delayA - 3]; + d1 = p->buf[delayA ] - (unsigned)p->buf[delayA - 1]; + d2 = p->buf[delayA - 1] - (unsigned)p->buf[delayA - 2]; + d3 = p->buf[delayA - 2] - (unsigned)p->buf[delayA - 3]; predictionA = d0 * p->coeffsA[filter][0] + d1 * p->coeffsA[filter][1] + @@ -1105,10 +1105,10 @@ p->filterA[filter] = p->lastA[filter] + ((int)(p->filterA[filter] * 31U) >> 5); sign = APESIGN(decoded); - p->coeffsA[filter][0] += ((d0 < 0) * 2 - 1) * sign; - p->coeffsA[filter][1] += ((d1 < 0) * 2 - 1) * sign; - p->coeffsA[filter][2] += ((d2 < 0) * 2 - 1) * sign; - p->coeffsA[filter][3] += ((d3 < 0) * 2 - 1) * sign; + p->coeffsA[filter][0] += (((int32_t)d0 < 0) * 2 - 1) * sign; + p->coeffsA[filter][1] += (((int32_t)d1 < 0) * 2 - 1) * sign; + p->coeffsA[filter][2] += (((int32_t)d2 < 0) * 2 - 1) * sign; + p->coeffsA[filter][3] += (((int32_t)d3 < 0) * 2 - 1) * sign; return p->filterA[filter]; } @@ -1587,7 +1587,7 @@ for (ch = 0; ch < s->channels; ch++) { sample8 = (uint8_t *)frame->data[ch]; for (i = 0; i < blockstodecode; i++) - *sample8++ = (s->decoded[ch][i] + 0x80) & 0xff; + *sample8++ = (s->decoded[ch][i] + 0x80U) & 0xff; } break; case 16: diff -Nru ffmpeg-4.4.1/libavcodec/argo.c ffmpeg-4.4.2/libavcodec/argo.c --- ffmpeg-4.4.1/libavcodec/argo.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/argo.c 2022-04-14 21:13:48.000000000 +0100 @@ -608,6 +608,9 @@ uint32_t chunk; int ret; + if (avpkt->size < 4) + return AVERROR_INVALIDDATA; + bytestream2_init(gb, avpkt->data, avpkt->size); if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0) diff -Nru ffmpeg-4.4.1/libavcodec/av1dec.c ffmpeg-4.4.2/libavcodec/av1dec.c --- ffmpeg-4.4.1/libavcodec/av1dec.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/av1dec.c 2022-04-14 21:13:38.000000000 +0100 @@ -28,6 +28,34 @@ #include "internal.h" #include "profiles.h" +/**< same with Div_Lut defined in spec 7.11.3.7 */ +static const uint16_t div_lut[AV1_DIV_LUT_NUM] = { + 16384, 16320, 16257, 16194, 16132, 16070, 16009, 15948, 15888, 15828, 15768, + 15709, 15650, 15592, 15534, 15477, 15420, 15364, 15308, 15252, 15197, 15142, + 15087, 15033, 14980, 14926, 14873, 14821, 14769, 14717, 14665, 14614, 14564, + 14513, 14463, 14413, 14364, 14315, 14266, 14218, 14170, 14122, 14075, 14028, + 13981, 13935, 13888, 13843, 13797, 13752, 13707, 13662, 13618, 13574, 13530, + 13487, 13443, 13400, 13358, 13315, 13273, 13231, 13190, 13148, 13107, 13066, + 13026, 12985, 12945, 12906, 12866, 12827, 12788, 12749, 12710, 12672, 12633, + 12596, 12558, 12520, 12483, 12446, 12409, 12373, 12336, 12300, 12264, 12228, + 12193, 12157, 12122, 12087, 12053, 12018, 11984, 11950, 11916, 11882, 11848, + 11815, 11782, 11749, 11716, 11683, 11651, 11619, 11586, 11555, 11523, 11491, + 11460, 11429, 11398, 11367, 11336, 11305, 11275, 11245, 11215, 11185, 11155, + 11125, 11096, 11067, 11038, 11009, 10980, 10951, 10923, 10894, 10866, 10838, + 10810, 10782, 10755, 10727, 10700, 10673, 10645, 10618, 10592, 10565, 10538, + 10512, 10486, 10460, 10434, 10408, 10382, 10356, 10331, 10305, 10280, 10255, + 10230, 10205, 10180, 10156, 10131, 10107, 10082, 10058, 10034, 10010, 9986, + 9963, 9939, 9916, 9892, 9869, 9846, 9823, 9800, 9777, 9754, 9732, + 9709, 9687, 9664, 9642, 9620, 9598, 9576, 9554, 9533, 9511, 9489, + 9468, 9447, 9425, 9404, 9383, 9362, 9341, 9321, 9300, 9279, 9259, + 9239, 9218, 9198, 9178, 9158, 9138, 9118, 9098, 9079, 9059, 9039, + 9020, 9001, 8981, 8962, 8943, 8924, 8905, 8886, 8867, 8849, 8830, + 8812, 8793, 8775, 8756, 8738, 8720, 8702, 8684, 8666, 8648, 8630, + 8613, 8595, 8577, 8560, 8542, 8525, 8508, 8490, 8473, 8456, 8439, + 8422, 8405, 8389, 8372, 8355, 8339, 8322, 8306, 8289, 8273, 8257, + 8240, 8224, 8208, 8192 +}; + static uint32_t inverse_recenter(int r, uint32_t v) { if (v > 2 * r) @@ -97,6 +125,70 @@ -mx, mx + 1, r) << prec_diff) + round; } +static uint64_t round_two(uint64_t x, uint16_t n) +{ + if (n == 0) + return x; + return ((x + ((uint64_t)1 << (n - 1))) >> n); +} + +static int64_t round_two_signed(int64_t x, uint16_t n) +{ + return ((x<0) ? -((int64_t)round_two(-x, n)) : (int64_t)round_two(x, n)); +} + +/** + * Resolve divisor process. + * see spec 7.11.3.7 + */ +static int16_t resolve_divisor(uint32_t d, uint16_t *shift) +{ + int32_t e, f; + + *shift = av_log2(d); + e = d - (1 << (*shift)); + if (*shift > AV1_DIV_LUT_BITS) + f = round_two(e, *shift - AV1_DIV_LUT_BITS); + else + f = e << (AV1_DIV_LUT_BITS - (*shift)); + + *shift += AV1_DIV_LUT_PREC_BITS; + + return div_lut[f]; +} + +/** + * check if global motion params is valid. + * see spec 7.11.3.6 + */ +static uint8_t get_shear_params_valid(AV1DecContext *s, int idx) +{ + int16_t alpha, beta, gamma, delta, divf, divs; + int64_t v, w; + int32_t *param = &s->cur_frame.gm_params[idx][0]; + if (param[2] < 0) + return 0; + + alpha = av_clip_int16(param[2] - (1 << AV1_WARPEDMODEL_PREC_BITS)); + beta = av_clip_int16(param[3]); + divf = resolve_divisor(abs(param[2]), &divs); + v = (int64_t)param[4] * (1 << AV1_WARPEDMODEL_PREC_BITS); + w = (int64_t)param[3] * param[4]; + gamma = av_clip_int16((int)round_two_signed((v * divf), divs)); + delta = av_clip_int16(param[5] - (int)round_two_signed((w * divf), divs) - (1 << AV1_WARPEDMODEL_PREC_BITS)); + + alpha = round_two_signed(alpha, AV1_WARP_PARAM_REDUCE_BITS) << AV1_WARP_PARAM_REDUCE_BITS; + beta = round_two_signed(beta, AV1_WARP_PARAM_REDUCE_BITS) << AV1_WARP_PARAM_REDUCE_BITS; + gamma = round_two_signed(gamma, AV1_WARP_PARAM_REDUCE_BITS) << AV1_WARP_PARAM_REDUCE_BITS; + delta = round_two_signed(delta, AV1_WARP_PARAM_REDUCE_BITS) << AV1_WARP_PARAM_REDUCE_BITS; + + if ((4 * abs(alpha) + 7 * abs(beta)) >= (1 << AV1_WARPEDMODEL_PREC_BITS) || + (4 * abs(gamma) + 4 * abs(delta)) >= (1 << AV1_WARPEDMODEL_PREC_BITS)) + return 0; + + return 1; +} + /** * update gm type/params, since cbs already implemented part of this funcation, * so we don't need to full implement spec. @@ -144,6 +236,9 @@ read_global_param(s, type, ref, 0); read_global_param(s, type, ref, 1); } + if (type <= AV1_WARP_MODEL_AFFINE) { + s->cur_frame.gm_invalid[ref] = !get_shear_params_valid(s, ref); + } } } @@ -509,6 +604,9 @@ dst->spatial_id = src->spatial_id; dst->temporal_id = src->temporal_id; + memcpy(dst->gm_invalid, + src->gm_invalid, + AV1_NUM_REF_FRAMES * sizeof(uint8_t)); memcpy(dst->gm_type, src->gm_type, AV1_NUM_REF_FRAMES * sizeof(uint8_t)); diff -Nru ffmpeg-4.4.1/libavcodec/av1dec.h ffmpeg-4.4.2/libavcodec/av1dec.h --- ffmpeg-4.4.1/libavcodec/av1dec.h 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/av1dec.h 2022-01-14 18:45:25.000000000 +0000 @@ -42,6 +42,7 @@ int temporal_id; int spatial_id; + uint8_t gm_invalid[AV1_NUM_REF_FRAMES]; uint8_t gm_type[AV1_NUM_REF_FRAMES]; int32_t gm_params[AV1_NUM_REF_FRAMES][6]; diff -Nru ffmpeg-4.4.1/libavcodec/av1.h ffmpeg-4.4.2/libavcodec/av1.h --- ffmpeg-4.4.1/libavcodec/av1.h 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/av1.h 2022-01-14 18:45:25.000000000 +0000 @@ -114,6 +114,13 @@ AV1_WARP_MODEL_TRANSLATION = 1, AV1_WARP_MODEL_ROTZOOM = 2, AV1_WARP_MODEL_AFFINE = 3, + AV1_WARP_PARAM_REDUCE_BITS = 6, + + AV1_DIV_LUT_BITS = 8, + AV1_DIV_LUT_PREC_BITS = 14, + AV1_DIV_LUT_NUM = 257, + + AV1_MAX_LOOP_FILTER = 63, }; diff -Nru ffmpeg-4.4.1/libavcodec/cbs_av1_syntax_template.c ffmpeg-4.4.2/libavcodec/cbs_av1_syntax_template.c --- ffmpeg-4.4.1/libavcodec/cbs_av1_syntax_template.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/cbs_av1_syntax_template.c 2022-01-14 18:45:25.000000000 +0000 @@ -355,7 +355,7 @@ AV1_REF_FRAME_ALTREF2, AV1_REF_FRAME_ALTREF }; int8_t ref_frame_idx[AV1_REFS_PER_FRAME], used_frame[AV1_NUM_REF_FRAMES]; - int8_t shifted_order_hints[AV1_NUM_REF_FRAMES]; + int16_t shifted_order_hints[AV1_NUM_REF_FRAMES]; int cur_frame_hint, latest_order_hint, earliest_order_hint, ref; int i, j; diff -Nru ffmpeg-4.4.1/libavcodec/cfhd.c ffmpeg-4.4.2/libavcodec/cfhd.c --- ffmpeg-4.4.1/libavcodec/cfhd.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/cfhd.c 2022-04-14 21:13:48.000000000 +0100 @@ -838,7 +838,7 @@ const uint16_t q = s->quantisation; for (i = 0; i < run; i++) { - *coeff_data |= coeff * 256; + *coeff_data |= coeff * 256U; *coeff_data++ *= q; } } else { @@ -869,7 +869,7 @@ const uint16_t q = s->quantisation; for (i = 0; i < run; i++) { - *coeff_data |= coeff * 256; + *coeff_data |= coeff * 256U; *coeff_data++ *= q; } } else { diff -Nru ffmpeg-4.4.1/libavcodec/diracdec.c ffmpeg-4.4.2/libavcodec/diracdec.c --- ffmpeg-4.4.1/libavcodec/diracdec.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/diracdec.c 2022-04-14 21:13:48.000000000 +0100 @@ -1432,8 +1432,8 @@ int *c = s->globalmc[ref].perspective; int64_t m = (1<u.mv[ref][0] = (mx + (1<<(ez+ep))) >> (ez+ep); block->u.mv[ref][1] = (my + (1<<(ez+ep))) >> (ez+ep); diff -Nru ffmpeg-4.4.1/libavcodec/dnxhdenc.c ffmpeg-4.4.2/libavcodec/dnxhdenc.c --- ffmpeg-4.4.1/libavcodec/dnxhdenc.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/dnxhdenc.c 2022-04-14 21:13:38.000000000 +0100 @@ -1353,7 +1353,7 @@ av_freep(&ctx->qmatrix_c16); av_freep(&ctx->qmatrix_l16); - if (avctx->active_thread_type == FF_THREAD_SLICE) { + if (ctx->thread[1]) { for (i = 1; i < avctx->thread_count; i++) av_freep(&ctx->thread[i]); } diff -Nru ffmpeg-4.4.1/libavcodec/dxva2_av1.c ffmpeg-4.4.2/libavcodec/dxva2_av1.c --- ffmpeg-4.4.1/libavcodec/dxva2_av1.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/dxva2_av1.c 2022-01-14 18:45:25.000000000 +0000 @@ -139,7 +139,7 @@ pp->frame_refs[i].Index = ref_frame->buf[0] ? ref_idx : 0xFF; /* Global Motion */ - pp->frame_refs[i].wminvalid = (h->cur_frame.gm_type[AV1_REF_FRAME_LAST + i] == AV1_WARP_MODEL_IDENTITY); + pp->frame_refs[i].wminvalid = h->cur_frame.gm_invalid[AV1_REF_FRAME_LAST + i]; pp->frame_refs[i].wmtype = h->cur_frame.gm_type[AV1_REF_FRAME_LAST + i]; for (j = 0; j < 6; ++j) { pp->frame_refs[i].wmmat[j] = h->cur_frame.gm_params[AV1_REF_FRAME_LAST + i][j]; diff -Nru ffmpeg-4.4.1/libavcodec/exr.c ffmpeg-4.4.2/libavcodec/exr.c --- ffmpeg-4.4.1/libavcodec/exr.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/exr.c 2022-04-14 21:13:48.000000000 +0100 @@ -1829,8 +1829,8 @@ dx = bytestream2_get_le32(gb); dy = bytestream2_get_le32(gb); - s->w = dx - sx + 1; - s->h = dy - sy + 1; + s->w = (unsigned)dx - sx + 1; + s->h = (unsigned)dy - sy + 1; continue; } else if ((var_size = check_header_variable(s, "lineOrder", diff -Nru ffmpeg-4.4.1/libavcodec/g729_parser.c ffmpeg-4.4.2/libavcodec/g729_parser.c --- ffmpeg-4.4.1/libavcodec/g729_parser.c 2021-10-21 18:06:35.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/g729_parser.c 2022-04-14 21:13:48.000000000 +0100 @@ -49,6 +49,9 @@ s->block_size = (avctx->bit_rate < 8000) ? G729D_6K4_BLOCK_SIZE : G729_8K_BLOCK_SIZE; if (avctx->codec_id == AV_CODEC_ID_ACELP_KELVIN) s->block_size++; + // channels > 2 is invalid, we pass the packet on unchanged + if (avctx->channels > 2) + s->block_size = 0; s->block_size *= avctx->channels; s->duration = avctx->frame_size; } diff -Nru ffmpeg-4.4.1/libavcodec/h263.h ffmpeg-4.4.2/libavcodec/h263.h --- ffmpeg-4.4.1/libavcodec/h263.h 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/h263.h 2022-04-14 21:13:38.000000000 +0100 @@ -100,15 +100,16 @@ static inline int h263_get_motion_length(int val, int f_code){ - int l, bit_size, code; + int bit_size, code, sign; if (val == 0) { return ff_mvtab[0][1]; } else { bit_size = f_code - 1; /* modulo encoding */ - l= INT_BIT - 6 - bit_size; - val = (val<>l; + val = sign_extend(val, 6 + bit_size); + sign = val >> 31; + val = (val ^ sign) - sign; /* val = FFABS(val) */ val--; code = (val >> bit_size) + 1; diff -Nru ffmpeg-4.4.1/libavcodec/jpeglsdec.c ffmpeg-4.4.2/libavcodec/jpeglsdec.c --- ffmpeg-4.4.1/libavcodec/jpeglsdec.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/jpeglsdec.c 2022-04-14 21:13:48.000000000 +0100 @@ -67,7 +67,7 @@ s->t3 = get_bits(&s->gb, 16); s->reset = get_bits(&s->gb, 16); - if(s->avctx->debug & FF_DEBUG_PICT_INFO) { + if (s->avctx->debug & FF_DEBUG_PICT_INFO) { av_log(s->avctx, AV_LOG_DEBUG, "Coding parameters maxval:%d T1:%d T2:%d T3:%d reset:%d\n", s->maxval, s->t1, s->t2, s->t3, s->reset); } @@ -96,7 +96,7 @@ else maxtab = 65530/wt - 1; - if(s->avctx->debug & FF_DEBUG_PICT_INFO) { + if (s->avctx->debug & FF_DEBUG_PICT_INFO) { av_log(s->avctx, AV_LOG_DEBUG, "LSE palette %d tid:%d wt:%d maxtab:%d\n", id, tid, wt, maxtab); } if (maxtab >= 256) { @@ -186,7 +186,7 @@ if (RItype) temp += state->N[Q] >> 1; - for (k = 0; (state->N[Q] << k) < temp; k++) + for (k = 0; ((unsigned)state->N[Q] << k) < temp; k++) ; #ifdef JLS_BROKEN @@ -195,6 +195,8 @@ #endif ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1, state->qbpp); + if (ret < 0) + return -0x10000; /* decode mapped error */ map = 0; @@ -209,7 +211,7 @@ ret = ret >> 1; } - if(FFABS(ret) > 0xFFFF) + if (FFABS(ret) > 0xFFFF) return -0x10000; /* update state */ state->A[Q] += FFABS(ret) - RItype; diff -Nru ffmpeg-4.4.1/libavcodec/libdav1d.c ffmpeg-4.4.2/libavcodec/libdav1d.c --- ffmpeg-4.4.1/libavcodec/libdav1d.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/libdav1d.c 2022-04-14 21:13:48.000000000 +0100 @@ -127,7 +127,11 @@ { Libdav1dContext *dav1d = c->priv_data; Dav1dSettings s; +#if FF_DAV1D_VERSION_AT_LEAST(6,0) + int threads = c->thread_count; +#else int threads = (c->thread_count ? c->thread_count : av_cpu_count()) * 3 / 2; +#endif int res; av_log(c, AV_LOG_INFO, "libdav1d %s\n", dav1d_version()); @@ -153,7 +157,7 @@ s.n_threads = FFMAX(dav1d->frame_threads, dav1d->tile_threads); else s.n_threads = FFMIN(threads, DAV1D_MAX_THREADS); - s.max_frame_delay = (c->flags & AV_CODEC_FLAG_LOW_DELAY) ? 1 : s.n_threads; + s.max_frame_delay = (c->flags & AV_CODEC_FLAG_LOW_DELAY) ? 1 : 0; av_log(c, AV_LOG_DEBUG, "Using %d threads, %d max_frame_delay\n", s.n_threads, s.max_frame_delay); #else @@ -244,8 +248,10 @@ if (res < 0) { if (res == AVERROR(EINVAL)) res = AVERROR_INVALIDDATA; - if (res != AVERROR(EAGAIN)) + if (res != AVERROR(EAGAIN)) { + dav1d_data_unref(data); return res; + } } res = dav1d_get_picture(dav1d->c, p); diff -Nru ffmpeg-4.4.1/libavcodec/libkvazaar.c ffmpeg-4.4.2/libavcodec/libkvazaar.c --- ffmpeg-4.4.1/libavcodec/libkvazaar.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/libkvazaar.c 2022-04-14 21:13:38.000000000 +0100 @@ -210,13 +210,19 @@ // Copy pixels from frame to input_pic. { + uint8_t *dst[4] = { + input_pic->data[0], + input_pic->data[1], + input_pic->data[2], + NULL, + }; int dst_linesizes[4] = { frame->width, frame->width / 2, frame->width / 2, 0 }; - av_image_copy(input_pic->data, dst_linesizes, + av_image_copy(dst, dst_linesizes, (const uint8_t **)frame->data, frame->linesize, frame->format, frame->width, frame->height); } diff -Nru ffmpeg-4.4.1/libavcodec/libopenh264dec.c ffmpeg-4.4.2/libavcodec/libopenh264dec.c --- ffmpeg-4.4.1/libavcodec/libopenh264dec.c 2021-10-21 18:06:35.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/libopenh264dec.c 2022-04-14 21:13:38.000000000 +0100 @@ -91,8 +91,8 @@ { SVCContext *s = avctx->priv_data; SBufferInfo info = { 0 }; - uint8_t* ptrs[3]; - int ret, linesize[3]; + uint8_t *ptrs[4] = { NULL }; + int ret, linesize[4]; AVFrame *avframe = data; DECODING_STATE state; #if OPENH264_VER_AT_LEAST(1, 7) @@ -140,6 +140,7 @@ linesize[0] = info.UsrData.sSystemBuffer.iStride[0]; linesize[1] = linesize[2] = info.UsrData.sSystemBuffer.iStride[1]; + linesize[3] = 0; av_image_copy(avframe->data, avframe->linesize, (const uint8_t **) ptrs, linesize, avctx->pix_fmt, avctx->width, avctx->height); avframe->pts = info.uiOutYuvTimeStamp; diff -Nru ffmpeg-4.4.1/libavcodec/libuavs3d.c ffmpeg-4.4.2/libavcodec/libuavs3d.c --- ffmpeg-4.4.1/libavcodec/libuavs3d.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/libuavs3d.c 2022-04-14 21:13:48.000000000 +0100 @@ -208,7 +208,9 @@ } avctx->has_b_frames = !seqh->low_delay; avctx->pix_fmt = seqh->bit_depth_internal == 8 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUV420P10LE; - ff_set_dimensions(avctx, seqh->horizontal_size, seqh->vertical_size); + ret = ff_set_dimensions(avctx, seqh->horizontal_size, seqh->vertical_size); + if (ret < 0) + return ret; h->got_seqhdr = 1; if (seqh->colour_description) { diff -Nru ffmpeg-4.4.1/libavcodec/Makefile ffmpeg-4.4.2/libavcodec/Makefile --- ffmpeg-4.4.1/libavcodec/Makefile 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/Makefile 2022-04-14 21:13:38.000000000 +0100 @@ -132,7 +132,6 @@ motion_est.o ratecontrol.o \ mpegvideoencdsp.o OBJS-$(CONFIG_MSS34DSP) += mss34dsp.o -OBJS-$(CONFIG_NVENC) += nvenc.o OBJS-$(CONFIG_PIXBLOCKDSP) += pixblockdsp.o OBJS-$(CONFIG_QPELDSP) += qpeldsp.o OBJS-$(CONFIG_QSV) += qsv.o @@ -375,9 +374,9 @@ OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_H264_MF_ENCODER) += mfenc.o mf_utils.o OBJS-$(CONFIG_H264_MMAL_DECODER) += mmaldec.o -OBJS-$(CONFIG_H264_NVENC_ENCODER) += nvenc_h264.o -OBJS-$(CONFIG_NVENC_ENCODER) += nvenc_h264.o -OBJS-$(CONFIG_NVENC_H264_ENCODER) += nvenc_h264.o +OBJS-$(CONFIG_H264_NVENC_ENCODER) += nvenc.o nvenc_h264.o +OBJS-$(CONFIG_NVENC_ENCODER) += nvenc.o nvenc_h264.o +OBJS-$(CONFIG_NVENC_H264_ENCODER) += nvenc.o nvenc_h264.o OBJS-$(CONFIG_H264_OMX_ENCODER) += omx.o OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec.o OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o @@ -397,8 +396,8 @@ OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_HEVC_MF_ENCODER) += mfenc.o mf_utils.o -OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o -OBJS-$(CONFIG_NVENC_HEVC_ENCODER) += nvenc_hevc.o +OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc.o nvenc_hevc.o +OBJS-$(CONFIG_NVENC_HEVC_ENCODER) += nvenc.o nvenc_hevc.o OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec.o OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o \ hevc_data.o @@ -875,6 +874,7 @@ OBJS-$(CONFIG_ADPCM_G726LE_DECODER) += g726.o OBJS-$(CONFIG_ADPCM_G726LE_ENCODER) += g726.o OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_AMV_ENCODER) += adpcmenc.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_ALP_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_ALP_ENCODER) += adpcmenc.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_APC_DECODER) += adpcm.o adpcm_data.o diff -Nru ffmpeg-4.4.1/libavcodec/mjpegbdec.c ffmpeg-4.4.2/libavcodec/mjpegbdec.c --- ffmpeg-4.4.1/libavcodec/mjpegbdec.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/mjpegbdec.c 2022-04-14 21:13:48.000000000 +0100 @@ -57,6 +57,7 @@ buf_end = buf + buf_size; s->got_picture = 0; s->adobe_transform = -1; + s->buf_size = buf_size; read_header: /* reset on every SOI */ diff -Nru ffmpeg-4.4.1/libavcodec/motion_est.c ffmpeg-4.4.2/libavcodec/motion_est.c --- ffmpeg-4.4.1/libavcodec/motion_est.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/motion_est.c 2022-04-14 21:13:48.000000000 +0100 @@ -1614,7 +1614,7 @@ for(y=0; ymb_height; y++){ int x; int xy= y*s->mb_stride; - for(x=0; xmb_width; x++){ + for(x=0; xmb_width; x++, xy++){ if(s->mb_type[xy] & type){ int mx= mv_table[xy][0]; int my= mv_table[xy][1]; @@ -1622,16 +1622,15 @@ fcode_tab[my + MAX_MV]); int j; - if(mx >= range || mx < -range || - my >= range || my < -range) - continue; + if (mx >= range || mx < -range || + my >= range || my < -range) + continue; for(j=0; jpict_type==AV_PICTURE_TYPE_B || s->current_picture.mc_mb_var[xy] < s->current_picture.mb_var[xy]) score[j]-= 170; } } - xy++; } } diff -Nru ffmpeg-4.4.1/libavcodec/movtextenc.c ffmpeg-4.4.2/libavcodec/movtextenc.c --- ffmpeg-4.4.1/libavcodec/movtextenc.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/movtextenc.c 2022-04-14 21:13:38.000000000 +0100 @@ -85,7 +85,7 @@ uint8_t box_flags; StyleBox d; uint16_t text_pos; - uint16_t byte_count; + unsigned byte_count; char **fonts; int font_count; double font_scale_factor; @@ -585,9 +585,9 @@ mov_text_ass_style_set(s, style); } -static uint16_t utf8_strlen(const char *text, int len) +static unsigned utf8_strlen(const char *text, int len) { - uint16_t i = 0, ret = 0; + unsigned i = 0, ret = 0; while (i < len) { char c = text[i]; if ((c & 0x80) == 0) @@ -607,7 +607,7 @@ static void mov_text_text_cb(void *priv, const char *text, int len) { - uint16_t utf8_len = utf8_strlen(text, len); + unsigned utf8_len = utf8_strlen(text, len); MovTextContext *s = priv; av_bprint_append_data(&s->buffer, text, len); // If it's not utf-8, just use the byte length diff -Nru ffmpeg-4.4.1/libavcodec/nvenc.c ffmpeg-4.4.2/libavcodec/nvenc.c --- ffmpeg-4.4.1/libavcodec/nvenc.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/nvenc.c 2022-04-14 21:13:38.000000000 +0100 @@ -1760,7 +1760,7 @@ NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs; AVHWFramesContext *frames_ctx = (AVHWFramesContext*)frame->hw_frames_ctx->data; - NV_ENC_REGISTER_RESOURCE reg; + NV_ENC_REGISTER_RESOURCE reg = { 0 }; int i, idx, ret; for (i = 0; i < ctx->nb_registered_frames; i++) { diff -Nru ffmpeg-4.4.1/libavcodec/opus_silk.c ffmpeg-4.4.2/libavcodec/opus_silk.c --- ffmpeg-4.4.1/libavcodec/opus_silk.c 2021-10-21 18:06:35.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/opus_silk.c 2022-01-14 18:45:25.000000000 +0000 @@ -198,7 +198,8 @@ } } -static void silk_lsp2poly(const int32_t lsp[16], int32_t pol[16], int half_order) +static void silk_lsp2poly(const int32_t lsp[/* 2 * half_order - 1 */], + int32_t pol[/* half_order + 1 */], int half_order) { int i, j; diff -Nru ffmpeg-4.4.1/libavcodec/pixlet.c ffmpeg-4.4.2/libavcodec/pixlet.c --- ffmpeg-4.4.1/libavcodec/pixlet.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/pixlet.c 2022-04-14 21:13:48.000000000 +0100 @@ -405,7 +405,7 @@ (int64_t) low [i - 1] * -INT64_C(325392907) + (int64_t) high[i + 0] * INT64_C(1518500249) + (int64_t) high[i - 1] * INT64_C(1518500249); - dest[i * 2] = av_clip_int16(((value >> 32) * scale) >> 32); + dest[i * 2] = av_clip_int16(((value >> 32) * (uint64_t)scale) >> 32); } for (i = 0; i < hsize; i++) { @@ -416,7 +416,7 @@ (int64_t) high[i + 1] * INT64_C(303700064) + (int64_t) high[i + 0] * -INT64_C(3644400640) + (int64_t) high[i - 1] * INT64_C(303700064); - dest[i * 2 + 1] = av_clip_int16(((value >> 32) * scale) >> 32); + dest[i * 2 + 1] = av_clip_int16(((value >> 32) * (uint64_t)scale) >> 32); } } diff -Nru ffmpeg-4.4.1/libavcodec/rasc.c ffmpeg-4.4.2/libavcodec/rasc.c --- ffmpeg-4.4.1/libavcodec/rasc.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/rasc.c 2022-04-14 21:13:38.000000000 +0100 @@ -722,6 +722,7 @@ break; default: bytestream2_skip(gb, size); + ret = 0; } if (ret < 0) diff -Nru ffmpeg-4.4.1/libavcodec/sonic.c ffmpeg-4.4.2/libavcodec/sonic.c --- ffmpeg-4.4.1/libavcodec/sonic.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/sonic.c 2022-04-14 21:13:48.000000000 +0100 @@ -1004,7 +1004,7 @@ // dequantize for (i = 0; i < s->num_taps; i++) - s->predictor_k[i] *= s->tap_quant[i]; + s->predictor_k[i] *= (unsigned) s->tap_quant[i]; if (s->lossless) quant = 1; diff -Nru ffmpeg-4.4.1/libavcodec/takdsp.c ffmpeg-4.4.2/libavcodec/takdsp.c --- ffmpeg-4.4.1/libavcodec/takdsp.c 2021-10-21 18:06:35.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/takdsp.c 2022-04-14 21:13:48.000000000 +0100 @@ -65,7 +65,7 @@ for (i = 0; i < length; i++) { int32_t a = p1[i]; int32_t b = p2[i]; - b = (unsigned)(dfactor * (b >> dshift) + 128 >> 8) << dshift; + b = (unsigned)((int)(dfactor * (unsigned)(b >> dshift) + 128) >> 8) << dshift; p1[i] = b - a; } } diff -Nru ffmpeg-4.4.1/libavcodec/tiff.c ffmpeg-4.4.2/libavcodec/tiff.c --- ffmpeg-4.4.1/libavcodec/tiff.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/tiff.c 2022-04-14 21:13:48.000000000 +0100 @@ -735,19 +735,6 @@ return 0; } -static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame) -{ - TiffContext *s = avctx->priv_data; - - s->jpgframe->width = s->width; - s->jpgframe->height = s->height; - - s->avctx_mjpeg->width = s->width; - s->avctx_mjpeg->height = s->height; - - return dng_decode_jpeg(avctx, frame, s->stripsize, 0, 0, s->width, s->height); -} - static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int stride, const uint8_t *src, int size, int strip_start, int lines) { @@ -869,7 +856,7 @@ av_log(s->avctx, AV_LOG_ERROR, "More than one DNG JPEG strips unsupported\n"); return AVERROR_PATCHWELCOME; } - if ((ret = dng_decode_strip(s->avctx, p)) < 0) + if ((ret = dng_decode_jpeg(s->avctx, p, s->stripsize, 0, 0, s->width, s->height)) < 0) return ret; return 0; } @@ -987,12 +974,6 @@ int pos_x = 0, pos_y = 0; int ret; - s->jpgframe->width = s->tile_width; - s->jpgframe->height = s->tile_length; - - s->avctx_mjpeg->width = s->tile_width; - s->avctx_mjpeg->height = s->tile_length; - has_width_leftover = (s->width % s->tile_width != 0); has_height_leftover = (s->height % s->tile_length != 0); @@ -2169,6 +2150,7 @@ s->avctx_mjpeg->flags2 = avctx->flags2; s->avctx_mjpeg->dct_algo = avctx->dct_algo; s->avctx_mjpeg->idct_algo = avctx->idct_algo; + s->avctx_mjpeg->max_pixels = avctx->max_pixels; ret = avcodec_open2(s->avctx_mjpeg, codec, NULL); if (ret < 0) { return ret; diff -Nru ffmpeg-4.4.1/libavcodec/vaapi_av1.c ffmpeg-4.4.2/libavcodec/vaapi_av1.c --- ffmpeg-4.4.1/libavcodec/vaapi_av1.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/vaapi_av1.c 2022-01-14 18:45:25.000000000 +0000 @@ -21,8 +21,28 @@ #include "libavutil/pixdesc.h" #include "hwconfig.h" #include "vaapi_decode.h" +#include "internal.h" #include "av1dec.h" +typedef struct VAAPIAV1FrameRef { + ThreadFrame frame; + int valid; +} VAAPIAV1FrameRef; + +typedef struct VAAPIAV1DecContext { + VAAPIDecodeContext base; + + /** + * For film grain case, VAAPI generate 2 output for each frame, + * current_frame will not apply film grain, and will be used for + * references for next frames. Maintain the reference list without + * applying film grain here. And current_display_picture will be + * used to apply film grain and push to downstream. + */ + VAAPIAV1FrameRef ref_tab[AV1_NUM_REF_FRAMES]; + ThreadFrame tmp_frame; +} VAAPIAV1DecContext; + static VASurfaceID vaapi_av1_surface_id(AV1Frame *vf) { if (vf) @@ -49,6 +69,48 @@ return bit_depth == 8 ? 0 : bit_depth == 10 ? 1 : 2; } +static int vaapi_av1_decode_init(AVCodecContext *avctx) +{ + VAAPIAV1DecContext *ctx = avctx->internal->hwaccel_priv_data; + + ctx->tmp_frame.f = av_frame_alloc(); + if (!ctx->tmp_frame.f) { + av_log(avctx, AV_LOG_ERROR, + "Failed to allocate frame.\n"); + return AVERROR(ENOMEM); + } + + for (int i = 0; i < FF_ARRAY_ELEMS(ctx->ref_tab); i++) { + ctx->ref_tab[i].frame.f = av_frame_alloc(); + if (!ctx->ref_tab[i].frame.f) { + av_log(avctx, AV_LOG_ERROR, + "Failed to allocate reference table frame %d.\n", i); + return AVERROR(ENOMEM); + } + ctx->ref_tab[i].valid = 0; + } + + return ff_vaapi_decode_init(avctx); +} + +static int vaapi_av1_decode_uninit(AVCodecContext *avctx) +{ + VAAPIAV1DecContext *ctx = avctx->internal->hwaccel_priv_data; + + if (ctx->tmp_frame.f->buf[0]) + ff_thread_release_buffer(avctx, &ctx->tmp_frame); + av_frame_free(&ctx->tmp_frame.f); + + for (int i = 0; i < FF_ARRAY_ELEMS(ctx->ref_tab); i++) { + if (ctx->ref_tab[i].frame.f->buf[0]) + ff_thread_release_buffer(avctx, &ctx->ref_tab[i].frame); + av_frame_free(&ctx->ref_tab[i].frame.f); + } + + return ff_vaapi_decode_uninit(avctx); +} + + static int vaapi_av1_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) @@ -58,40 +120,62 @@ const AV1RawFrameHeader *frame_header = s->raw_frame_header; const AV1RawFilmGrainParams *film_grain = &s->cur_frame.film_grain; VAAPIDecodePicture *pic = s->cur_frame.hwaccel_picture_private; + VAAPIAV1DecContext *ctx = avctx->internal->hwaccel_priv_data; VADecPictureParameterBufferAV1 pic_param; int8_t bit_depth_idx; int err = 0; int apply_grain = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) && film_grain->apply_grain; uint8_t remap_lr_type[4] = {AV1_RESTORE_NONE, AV1_RESTORE_SWITCHABLE, AV1_RESTORE_WIENER, AV1_RESTORE_SGRPROJ}; - - pic->output_surface = vaapi_av1_surface_id(&s->cur_frame); + uint8_t segmentation_feature_signed[AV1_SEG_LVL_MAX] = {1, 1, 1, 1, 1, 0, 0, 0}; + uint8_t segmentation_feature_max[AV1_SEG_LVL_MAX] = {255, AV1_MAX_LOOP_FILTER, + AV1_MAX_LOOP_FILTER, AV1_MAX_LOOP_FILTER, AV1_MAX_LOOP_FILTER, 7 , 0 , 0 }; bit_depth_idx = vaapi_av1_get_bit_depth_idx(avctx); if (bit_depth_idx < 0) goto fail; + if (apply_grain) { + if (ctx->tmp_frame.f->buf[0]) + ff_thread_release_buffer(avctx, &ctx->tmp_frame); + err = ff_thread_get_buffer(avctx, &ctx->tmp_frame, AV_GET_BUFFER_FLAG_REF); + if (err < 0) + goto fail; + pic->output_surface = ff_vaapi_get_surface_id(ctx->tmp_frame.f); + } else { + pic->output_surface = vaapi_av1_surface_id(&s->cur_frame); + } + memset(&pic_param, 0, sizeof(VADecPictureParameterBufferAV1)); pic_param = (VADecPictureParameterBufferAV1) { - .profile = seq->seq_profile, - .order_hint_bits_minus_1 = seq->order_hint_bits_minus_1, - .bit_depth_idx = bit_depth_idx, - .current_frame = pic->output_surface, - .current_display_picture = pic->output_surface, - .frame_width_minus1 = frame_header->frame_width_minus_1, - .frame_height_minus1 = frame_header->frame_height_minus_1, - .primary_ref_frame = frame_header->primary_ref_frame, - .order_hint = frame_header->order_hint, - .tile_cols = frame_header->tile_cols, - .tile_rows = frame_header->tile_rows, - .context_update_tile_id = frame_header->context_update_tile_id, - .interp_filter = frame_header->interpolation_filter, - .filter_level[0] = frame_header->loop_filter_level[0], - .filter_level[1] = frame_header->loop_filter_level[1], - .filter_level_u = frame_header->loop_filter_level[2], - .filter_level_v = frame_header->loop_filter_level[3], - .base_qindex = frame_header->base_q_idx, - .cdef_damping_minus_3 = frame_header->cdef_damping_minus_3, - .cdef_bits = frame_header->cdef_bits, + .profile = seq->seq_profile, + .order_hint_bits_minus_1 = seq->order_hint_bits_minus_1, + .bit_depth_idx = bit_depth_idx, + .matrix_coefficients = seq->color_config.matrix_coefficients, + .current_frame = pic->output_surface, + .current_display_picture = vaapi_av1_surface_id(&s->cur_frame), + .frame_width_minus1 = frame_header->frame_width_minus_1, + .frame_height_minus1 = frame_header->frame_height_minus_1, + .primary_ref_frame = frame_header->primary_ref_frame, + .order_hint = frame_header->order_hint, + .tile_cols = frame_header->tile_cols, + .tile_rows = frame_header->tile_rows, + .context_update_tile_id = frame_header->context_update_tile_id, + .superres_scale_denominator = frame_header->use_superres ? + frame_header->coded_denom + AV1_SUPERRES_DENOM_MIN : + AV1_SUPERRES_NUM, + .interp_filter = frame_header->interpolation_filter, + .filter_level[0] = frame_header->loop_filter_level[0], + .filter_level[1] = frame_header->loop_filter_level[1], + .filter_level_u = frame_header->loop_filter_level[2], + .filter_level_v = frame_header->loop_filter_level[3], + .base_qindex = frame_header->base_q_idx, + .y_dc_delta_q = frame_header->delta_q_y_dc, + .u_dc_delta_q = frame_header->delta_q_u_dc, + .u_ac_delta_q = frame_header->delta_q_u_ac, + .v_dc_delta_q = frame_header->delta_q_v_dc, + .v_ac_delta_q = frame_header->delta_q_v_ac, + .cdef_damping_minus_3 = frame_header->cdef_damping_minus_3, + .cdef_bits = frame_header->cdef_bits, .seq_info_fields.fields = { .still_picture = seq->still_picture, .use_128x128_superblock = seq->use_128x128_superblock, @@ -162,12 +246,15 @@ .mode_ref_delta_update = frame_header->loop_filter_delta_update, }, .mode_control_fields.bits = { - .delta_q_present_flag = frame_header->delta_q_present, - .log2_delta_q_res = frame_header->delta_q_res, - .tx_mode = frame_header->tx_mode, - .reference_select = frame_header->reference_select, - .reduced_tx_set_used = frame_header->reduced_tx_set, - .skip_mode_present = frame_header->skip_mode_present, + .delta_q_present_flag = frame_header->delta_q_present, + .log2_delta_q_res = frame_header->delta_q_res, + .delta_lf_present_flag = frame_header->delta_lf_present, + .log2_delta_lf_res = frame_header->delta_lf_res, + .delta_lf_multi = frame_header->delta_lf_multi, + .tx_mode = frame_header->tx_mode, + .reference_select = frame_header->reference_select, + .reduced_tx_set_used = frame_header->reduced_tx_set, + .skip_mode_present = frame_header->skip_mode_present, }, .loop_restoration_fields.bits = { .yframe_restoration_type = remap_lr_type[frame_header->lr_type[0]], @@ -178,6 +265,9 @@ }, .qmatrix_fields.bits = { .using_qmatrix = frame_header->using_qmatrix, + .qm_y = frame_header->qm_y, + .qm_u = frame_header->qm_u, + .qm_v = frame_header->qm_v, } }; @@ -185,7 +275,9 @@ if (pic_param.pic_info_fields.bits.frame_type == AV1_FRAME_KEY) pic_param.ref_frame_map[i] = VA_INVALID_ID; else - pic_param.ref_frame_map[i] = vaapi_av1_surface_id(&s->ref[i]); + pic_param.ref_frame_map[i] = ctx->ref_tab[i].valid ? + ff_vaapi_get_surface_id(ctx->ref_tab[i].frame.f) : + vaapi_av1_surface_id(&s->ref[i]); } for (int i = 0; i < AV1_REFS_PER_FRAME; i++) { pic_param.ref_frame_idx[i] = frame_header->ref_frame_idx[i]; @@ -213,10 +305,22 @@ frame_header->height_in_sbs_minus_1[i]; } for (int i = AV1_REF_FRAME_LAST; i <= AV1_REF_FRAME_ALTREF; i++) { - pic_param.wm[i - 1].wmtype = s->cur_frame.gm_type[i]; + pic_param.wm[i - 1].invalid = s->cur_frame.gm_invalid[i]; + pic_param.wm[i - 1].wmtype = s->cur_frame.gm_type[i]; for (int j = 0; j < 6; j++) pic_param.wm[i - 1].wmmat[j] = s->cur_frame.gm_params[i][j]; } + for (int i = 0; i < AV1_MAX_SEGMENTS; i++) { + for (int j = 0; j < AV1_SEG_LVL_MAX; j++) { + pic_param.seg_info.feature_mask[i] |= (frame_header->feature_enabled[i][j] << j); + if (segmentation_feature_signed[j]) + pic_param.seg_info.feature_data[i][j] = av_clip(frame_header->feature_value[i][j], + -segmentation_feature_max[j], segmentation_feature_max[j]); + else + pic_param.seg_info.feature_data[i][j] = av_clip(frame_header->feature_value[i][j], + 0, segmentation_feature_max[j]); + } + } if (apply_grain) { for (int i = 0; i < film_grain->num_y_points; i++) { pic_param.film_grain_info.point_y_value[i] = @@ -263,8 +367,34 @@ static int vaapi_av1_end_frame(AVCodecContext *avctx) { const AV1DecContext *s = avctx->priv_data; + const AV1RawFrameHeader *header = s->raw_frame_header; + const AV1RawFilmGrainParams *film_grain = &s->cur_frame.film_grain; VAAPIDecodePicture *pic = s->cur_frame.hwaccel_picture_private; - return ff_vaapi_decode_issue(avctx, pic); + VAAPIAV1DecContext *ctx = avctx->internal->hwaccel_priv_data; + + int apply_grain = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) && film_grain->apply_grain; + int ret; + ret = ff_vaapi_decode_issue(avctx, pic); + if (ret < 0) + return ret; + + for (int i = 0; i < AV1_NUM_REF_FRAMES; i++) { + if (header->refresh_frame_flags & (1 << i)) { + if (ctx->ref_tab[i].frame.f->buf[0]) + ff_thread_release_buffer(avctx, &ctx->ref_tab[i].frame); + + if (apply_grain) { + ret = ff_thread_ref_frame(&ctx->ref_tab[i].frame, &ctx->tmp_frame); + if (ret < 0) + return ret; + ctx->ref_tab[i].valid = 1; + } else { + ctx->ref_tab[i].valid = 0; + } + } + } + + return 0; } static int vaapi_av1_decode_slice(AVCodecContext *avctx, @@ -311,9 +441,9 @@ .end_frame = vaapi_av1_end_frame, .decode_slice = vaapi_av1_decode_slice, .frame_priv_data_size = sizeof(VAAPIDecodePicture), - .init = ff_vaapi_decode_init, - .uninit = ff_vaapi_decode_uninit, + .init = vaapi_av1_decode_init, + .uninit = vaapi_av1_decode_uninit, .frame_params = ff_vaapi_common_frame_params, - .priv_data_size = sizeof(VAAPIDecodeContext), + .priv_data_size = sizeof(VAAPIAV1DecContext), .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff -Nru ffmpeg-4.4.1/libavcodec/vaapi_decode.c ffmpeg-4.4.2/libavcodec/vaapi_decode.c --- ffmpeg-4.4.1/libavcodec/vaapi_decode.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/vaapi_decode.c 2022-04-14 21:13:38.000000000 +0100 @@ -577,10 +577,10 @@ switch (avctx->codec_id) { case AV_CODEC_ID_H264: case AV_CODEC_ID_HEVC: + case AV_CODEC_ID_AV1: frames->initial_pool_size += 16; break; case AV_CODEC_ID_VP9: - case AV_CODEC_ID_AV1: frames->initial_pool_size += 8; break; case AV_CODEC_ID_VP8: diff -Nru ffmpeg-4.4.1/libavcodec/vaapi_encode.c ffmpeg-4.4.2/libavcodec/vaapi_encode.c --- ffmpeg-4.4.1/libavcodec/vaapi_encode.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/vaapi_encode.c 2022-04-14 21:13:38.000000000 +0100 @@ -2366,6 +2366,11 @@ VAStatus vas; int err; + ctx->va_config = VA_INVALID_ID; + ctx->va_context = VA_INVALID_ID; + + /* If you add something that can fail above this av_frame_alloc(), + * modify ff_vaapi_encode_close() accordingly. */ ctx->frame = av_frame_alloc(); if (!ctx->frame) { return AVERROR(ENOMEM); @@ -2377,9 +2382,6 @@ return AVERROR(EINVAL); } - ctx->va_config = VA_INVALID_ID; - ctx->va_context = VA_INVALID_ID; - ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx); if (!ctx->input_frames_ref) { err = AVERROR(ENOMEM); @@ -2531,6 +2533,11 @@ VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodePicture *pic, *next; + /* We check ctx->frame to know whether ff_vaapi_encode_init() + * has been called and va_config/va_context initialized. */ + if (!ctx->frame) + return 0; + for (pic = ctx->pic_start; pic; pic = next) { next = pic->next; vaapi_encode_free(avctx, pic); diff -Nru ffmpeg-4.4.1/libavcodec/vp3.c ffmpeg-4.4.2/libavcodec/vp3.c --- ffmpeg-4.4.1/libavcodec/vp3.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/vp3.c 2022-04-14 21:13:48.000000000 +0100 @@ -2691,7 +2691,14 @@ skip_bits(&gb, 4); /* width code */ skip_bits(&gb, 4); /* height code */ if (s->version) { - s->version = get_bits(&gb, 5); + int version = get_bits(&gb, 5); +#if !CONFIG_VP4_DECODER + if (version >= 2) { + av_log(avctx, AV_LOG_ERROR, "This build does not support decoding VP4.\n"); + return AVERROR_DECODER_NOT_FOUND; + } +#endif + s->version = version; if (avctx->frame_number == 0) av_log(s->avctx, AV_LOG_DEBUG, "VP version: %d\n", s->version); diff -Nru ffmpeg-4.4.1/libavcodec/vqavideo.c ffmpeg-4.4.2/libavcodec/vqavideo.c --- ffmpeg-4.4.1/libavcodec/vqavideo.c 2021-10-21 18:06:35.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/vqavideo.c 2022-04-14 21:13:48.000000000 +0100 @@ -588,13 +588,14 @@ if (s->partial_countdown <= 0) { bytestream2_init(&s->gb, s->next_codebook_buffer, s->next_codebook_buffer_index); /* decompress codebook */ - if ((res = decode_format80(s, s->next_codebook_buffer_index, - s->codebook, s->codebook_size, 0)) < 0) - return res; + res = decode_format80(s, s->next_codebook_buffer_index, + s->codebook, s->codebook_size, 0); /* reset accounting */ s->next_codebook_buffer_index = 0; s->partial_countdown = s->partial_count; + if (res < 0) + return res; } } diff -Nru ffmpeg-4.4.1/libavcodec/wmadec.c ffmpeg-4.4.2/libavcodec/wmadec.c --- ffmpeg-4.4.1/libavcodec/wmadec.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/wmadec.c 2022-04-14 21:13:38.000000000 +0100 @@ -980,6 +980,7 @@ .capabilities = AV_CODEC_CAP_DR1, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif #if CONFIG_WMAV2_DECODER @@ -996,5 +997,6 @@ .capabilities = AV_CODEC_CAP_DR1, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif diff -Nru ffmpeg-4.4.1/libavcodec/wmaenc.c ffmpeg-4.4.2/libavcodec/wmaenc.c --- ffmpeg-4.4.1/libavcodec/wmaenc.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/wmaenc.c 2022-04-14 21:13:38.000000000 +0100 @@ -436,6 +436,7 @@ .close = ff_wma_end, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif #if CONFIG_WMAV2_ENCODER @@ -450,5 +451,6 @@ .close = ff_wma_end, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif diff -Nru ffmpeg-4.4.1/libavcodec/zmbvenc.c ffmpeg-4.4.2/libavcodec/zmbvenc.c --- ffmpeg-4.4.1/libavcodec/zmbvenc.c 2021-10-21 18:06:35.000000000 +0100 +++ ffmpeg-4.4.2/libavcodec/zmbvenc.c 2022-04-14 21:13:38.000000000 +0100 @@ -73,6 +73,7 @@ int keyint, curfrm; int bypp; enum ZmbvFormat fmt; + int zlib_init_ok; z_stream zstream; int score_tab[ZMBV_BLOCK * ZMBV_BLOCK * 4 + 1]; @@ -310,8 +311,9 @@ av_freep(&c->comp_buf); av_freep(&c->work_buf); - deflateEnd(&c->zstream); av_freep(&c->prev_buf); + if (c->zlib_init_ok) + deflateEnd(&c->zstream); return 0; } @@ -381,8 +383,6 @@ return AVERROR(EINVAL); } - // Needed if zlib unused or init aborted before deflateInit - memset(&c->zstream, 0, sizeof(z_stream)); c->comp_size = avctx->width * c->bypp * avctx->height + 1024 + ((avctx->width + ZMBV_BLOCK - 1) / ZMBV_BLOCK) * ((avctx->height + ZMBV_BLOCK - 1) / ZMBV_BLOCK) * 2 + 4; if (!(c->work_buf = av_malloc(c->comp_size))) { @@ -424,6 +424,7 @@ av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); return -1; } + c->zlib_init_ok = 1; return 0; } @@ -445,4 +446,5 @@ #endif //ZMBV_ENABLE_24BPP AV_PIX_FMT_BGR0, AV_PIX_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff -Nru ffmpeg-4.4.1/libavdevice/xv.c ffmpeg-4.4.2/libavdevice/xv.c --- ffmpeg-4.4.1/libavdevice/xv.c 2021-10-21 18:06:35.000000000 +0100 +++ ffmpeg-4.4.2/libavdevice/xv.c 2022-04-14 21:13:38.000000000 +0100 @@ -296,7 +296,7 @@ { XVContext *xv = s->priv_data; XvImage *img = xv->yuv_image; - uint8_t *data[3] = { + uint8_t *data[4] = { img->data + img->offsets[0], img->data + img->offsets[1], img->data + img->offsets[2] diff -Nru ffmpeg-4.4.1/libavfilter/aeval.c ffmpeg-4.4.2/libavfilter/aeval.c --- ffmpeg-4.4.1/libavfilter/aeval.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavfilter/aeval.c 2022-04-14 21:13:38.000000000 +0100 @@ -124,11 +124,10 @@ } #define ADD_EXPRESSION(expr_) do { \ - if (!av_dynarray2_add((void **)&eval->expr, &eval->nb_channels, \ - sizeof(*eval->expr), NULL)) { \ - ret = AVERROR(ENOMEM); \ + ret = av_dynarray_add_nofree(&eval->expr, \ + &eval->nb_channels, NULL); \ + if (ret < 0) \ goto end; \ - } \ eval->expr[eval->nb_channels-1] = NULL; \ ret = av_expr_parse(&eval->expr[eval->nb_channels - 1], expr_, \ var_names, func1_names, func1, \ diff -Nru ffmpeg-4.4.1/libavfilter/af_surround.c ffmpeg-4.4.2/libavfilter/af_surround.c --- ffmpeg-4.4.1/libavfilter/af_surround.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavfilter/af_surround.c 2022-04-14 21:13:38.000000000 +0100 @@ -203,13 +203,13 @@ s->rdft = av_calloc(inlink->channels, sizeof(*s->rdft)); if (!s->rdft) return AVERROR(ENOMEM); + s->nb_in_channels = inlink->channels; for (ch = 0; ch < inlink->channels; ch++) { s->rdft[ch] = av_rdft_init(ff_log2(s->buf_size), DFT_R2C); if (!s->rdft[ch]) return AVERROR(ENOMEM); } - s->nb_in_channels = inlink->channels; s->input_levels = av_malloc_array(s->nb_in_channels, sizeof(*s->input_levels)); if (!s->input_levels) return AVERROR(ENOMEM); @@ -266,13 +266,13 @@ s->irdft = av_calloc(outlink->channels, sizeof(*s->irdft)); if (!s->irdft) return AVERROR(ENOMEM); + s->nb_out_channels = outlink->channels; for (ch = 0; ch < outlink->channels; ch++) { s->irdft[ch] = av_rdft_init(ff_log2(s->buf_size), IDFT_C2R); if (!s->irdft[ch]) return AVERROR(ENOMEM); } - s->nb_out_channels = outlink->channels; s->output_levels = av_malloc_array(s->nb_out_channels, sizeof(*s->output_levels)); if (!s->output_levels) return AVERROR(ENOMEM); diff -Nru ffmpeg-4.4.1/libavfilter/af_vibrato.c ffmpeg-4.4.2/libavfilter/af_vibrato.c --- ffmpeg-4.4.1/libavfilter/af_vibrato.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavfilter/af_vibrato.c 2022-04-14 21:13:38.000000000 +0100 @@ -157,11 +157,11 @@ int c; AVFilterContext *ctx = inlink->dst; VibratoContext *s = ctx->priv; - s->channels = inlink->channels; s->buf = av_calloc(inlink->channels, sizeof(*s->buf)); if (!s->buf) return AVERROR(ENOMEM); + s->channels = inlink->channels; s->buf_size = lrint(inlink->sample_rate * 0.005 + 0.5); for (c = 0; c < s->channels; c++) { s->buf[c] = av_malloc_array(s->buf_size, sizeof(*s->buf[c])); diff -Nru ffmpeg-4.4.1/libavfilter/asrc_flite.c ffmpeg-4.4.2/libavfilter/asrc_flite.c --- ffmpeg-4.4.1/libavfilter/asrc_flite.c 2021-10-21 18:06:35.000000000 +0100 +++ ffmpeg-4.4.2/libavfilter/asrc_flite.c 2022-04-14 21:13:38.000000000 +0100 @@ -196,10 +196,12 @@ { FliteContext *flite = ctx->priv; - if (!--flite->voice_entry->usage_count) - flite->voice_entry->unregister_fn(flite->voice); - flite->voice = NULL; - flite->voice_entry = NULL; + if (flite->voice_entry) { + if (!--flite->voice_entry->usage_count) { + flite->voice_entry->unregister_fn(flite->voice); + flite->voice_entry->voice = NULL; + } + } delete_wave(flite->wave); flite->wave = NULL; } diff -Nru ffmpeg-4.4.1/libavfilter/avfilter.c ffmpeg-4.4.2/libavfilter/avfilter.c --- ffmpeg-4.4.1/libavfilter/avfilter.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavfilter/avfilter.c 2022-04-14 21:13:38.000000000 +0100 @@ -925,6 +925,8 @@ ret = ctx->filter->init(ctx); else if (ctx->filter->init_dict) ret = ctx->filter->init_dict(ctx, options); + if (ret < 0) + return ret; if (ctx->enable_str) { ret = set_enable_expr(ctx, ctx->enable_str); @@ -932,7 +934,7 @@ return ret; } - return ret; + return 0; } int avfilter_init_str(AVFilterContext *filter, const char *args) diff -Nru ffmpeg-4.4.1/libavfilter/vf_idet.c ffmpeg-4.4.2/libavfilter/vf_idet.c --- ffmpeg-4.4.1/libavfilter/vf_idet.c 2021-10-21 18:06:35.000000000 +0100 +++ ffmpeg-4.4.2/libavfilter/vf_idet.c 2022-04-14 21:13:38.000000000 +0100 @@ -336,20 +336,19 @@ static av_cold void uninit(AVFilterContext *ctx) { IDETContext *idet = ctx->priv; - int level = strncmp(ctx->name, "auto-inserted", 13) ? AV_LOG_INFO : AV_LOG_DEBUG; - av_log(ctx, level, "Repeated Fields: Neither:%6"PRId64" Top:%6"PRId64" Bottom:%6"PRId64"\n", + av_log(ctx, AV_LOG_INFO, "Repeated Fields: Neither:%6"PRId64" Top:%6"PRId64" Bottom:%6"PRId64"\n", idet->total_repeats[REPEAT_NONE], idet->total_repeats[REPEAT_TOP], idet->total_repeats[REPEAT_BOTTOM] ); - av_log(ctx, level, "Single frame detection: TFF:%6"PRId64" BFF:%6"PRId64" Progressive:%6"PRId64" Undetermined:%6"PRId64"\n", + av_log(ctx, AV_LOG_INFO, "Single frame detection: TFF:%6"PRId64" BFF:%6"PRId64" Progressive:%6"PRId64" Undetermined:%6"PRId64"\n", idet->total_prestat[TFF], idet->total_prestat[BFF], idet->total_prestat[PROGRESSIVE], idet->total_prestat[UNDETERMINED] ); - av_log(ctx, level, "Multi frame detection: TFF:%6"PRId64" BFF:%6"PRId64" Progressive:%6"PRId64" Undetermined:%6"PRId64"\n", + av_log(ctx, AV_LOG_INFO, "Multi frame detection: TFF:%6"PRId64" BFF:%6"PRId64" Progressive:%6"PRId64" Undetermined:%6"PRId64"\n", idet->total_poststat[TFF], idet->total_poststat[BFF], idet->total_poststat[PROGRESSIVE], diff -Nru ffmpeg-4.4.1/libavfilter/vf_subtitles.c ffmpeg-4.4.2/libavfilter/vf_subtitles.c --- ffmpeg-4.4.1/libavfilter/vf_subtitles.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavfilter/vf_subtitles.c 2022-04-14 21:13:48.000000000 +0100 @@ -145,9 +145,16 @@ ff_draw_init(&ass->draw, inlink->format, ass->alpha ? FF_DRAW_PROCESS_ALPHA : 0); ass_set_frame_size (ass->renderer, inlink->w, inlink->h); - if (ass->original_w && ass->original_h) + if (ass->original_w && ass->original_h) { ass_set_aspect_ratio(ass->renderer, (double)inlink->w / inlink->h, (double)ass->original_w / ass->original_h); +#if LIBASS_VERSION > 0x01010000 + ass_set_storage_size(ass->renderer, ass->original_w, ass->original_h); + } else { + ass_set_storage_size(ass->renderer, inlink->w, inlink->h); +#endif + } + if (ass->shaping != -1) ass_set_shaper(ass->renderer, ass->shaping); diff -Nru ffmpeg-4.4.1/libavfilter/vf_w3fdif.c ffmpeg-4.4.2/libavfilter/vf_w3fdif.c --- ffmpeg-4.4.1/libavfilter/vf_w3fdif.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavfilter/vf_w3fdif.c 2022-04-14 21:13:38.000000000 +0100 @@ -283,7 +283,7 @@ AVFilterContext *ctx = inlink->dst; W3FDIFContext *s = ctx->priv; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - int ret, i, depth; + int ret, i, depth, nb_threads; if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0) return ret; @@ -297,10 +297,11 @@ } s->nb_planes = av_pix_fmt_count_planes(inlink->format); - s->nb_threads = ff_filter_get_nb_threads(ctx); - s->work_line = av_calloc(s->nb_threads, sizeof(*s->work_line)); + nb_threads = ff_filter_get_nb_threads(ctx); + s->work_line = av_calloc(nb_threads, sizeof(*s->work_line)); if (!s->work_line) return AVERROR(ENOMEM); + s->nb_threads = nb_threads; for (i = 0; i < s->nb_threads; i++) { s->work_line[i] = av_calloc(FFALIGN(s->linesize[0], 32), sizeof(*s->work_line[0])); diff -Nru ffmpeg-4.4.1/libavformat/4xm.c ffmpeg-4.4.2/libavformat/4xm.c --- ffmpeg-4.4.1/libavformat/4xm.c 2021-10-21 18:06:35.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/4xm.c 2022-04-14 21:13:48.000000000 +0100 @@ -137,7 +137,8 @@ return AVERROR_INVALIDDATA; track = AV_RL32(buf + 8); - if ((unsigned)track >= UINT_MAX / sizeof(AudioTrack) - 1) { + if ((unsigned)track >= UINT_MAX / sizeof(AudioTrack) - 1 || + track >= s->max_streams) { av_log(s, AV_LOG_ERROR, "current_track too large\n"); return AVERROR_INVALIDDATA; } @@ -148,6 +149,9 @@ memset(&fourxm->tracks[fourxm->track_count], 0, sizeof(AudioTrack) * (track + 1 - fourxm->track_count)); fourxm->track_count = track + 1; + } else { + if (fourxm->tracks[track].bits) + return AVERROR_INVALIDDATA; } fourxm->tracks[track].adpcm = AV_RL32(buf + 12); fourxm->tracks[track].channels = AV_RL32(buf + 36); diff -Nru ffmpeg-4.4.1/libavformat/aadec.c ffmpeg-4.4.2/libavformat/aadec.c --- ffmpeg-4.4.1/libavformat/aadec.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/aadec.c 2022-04-14 21:13:38.000000000 +0100 @@ -130,8 +130,8 @@ AV_WB32(&header_key[idx * 4], header_key_part[idx]); // convert each part to BE! } av_log(s, AV_LOG_DEBUG, "Processed HeaderKey is "); - for (i = 0; i < 16; i++) - av_log(s, AV_LOG_DEBUG, "%02x", header_key[i]); + for (int j = 0; j < 16; j++) + av_log(s, AV_LOG_DEBUG, "%02x", header_key[j]); av_log(s, AV_LOG_DEBUG, "\n"); } else { av_dict_set(&s->metadata, key, val, 0); diff -Nru ffmpeg-4.4.1/libavformat/aiffdec.c ffmpeg-4.4.2/libavformat/aiffdec.c --- ffmpeg-4.4.1/libavformat/aiffdec.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/aiffdec.c 2022-04-14 21:13:48.000000000 +0100 @@ -120,6 +120,9 @@ sample_rate = val << exp; else sample_rate = (val + (1ULL<<(-exp-1))) >> -exp; + if (sample_rate <= 0) + return AVERROR_INVALIDDATA; + par->sample_rate = sample_rate; if (size < 18) return AVERROR_INVALIDDATA; @@ -182,8 +185,10 @@ par->block_align = (av_get_bits_per_sample(par->codec_id) * par->channels) >> 3; if (aiff->block_duration) { - par->bit_rate = (int64_t)par->sample_rate * (par->block_align << 3) / - aiff->block_duration; + par->bit_rate = av_rescale(par->sample_rate, par->block_align * 8LL, + aiff->block_duration); + if (par->bit_rate < 0) + par->bit_rate = 0; } /* Chunk is over */ @@ -365,7 +370,7 @@ if (!st->codecpar->block_align && st->codecpar->codec_id == AV_CODEC_ID_QCELP) { av_log(s, AV_LOG_WARNING, "qcelp without wave chunk, assuming full rate\n"); st->codecpar->block_align = 35; - } else if (!st->codecpar->block_align) { + } else if (st->codecpar->block_align <= 0) { av_log(s, AV_LOG_ERROR, "could not find COMM tag or invalid block_align value\n"); return -1; } diff -Nru ffmpeg-4.4.1/libavformat/aqtitledec.c ffmpeg-4.4.2/libavformat/aqtitledec.c --- ffmpeg-4.4.1/libavformat/aqtitledec.c 2021-10-21 18:06:35.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/aqtitledec.c 2022-04-14 21:13:48.000000000 +0100 @@ -74,7 +74,8 @@ new_event = 1; pos = avio_tell(s->pb); if (sub) { - sub->duration = frame - sub->pts; + if (frame >= sub->pts && (uint64_t)frame - sub->pts < INT64_MAX) + sub->duration = frame - sub->pts; sub = NULL; } } else if (*line) { diff -Nru ffmpeg-4.4.1/libavformat/argo_asf.c ffmpeg-4.4.2/libavformat/argo_asf.c --- ffmpeg-4.4.1/libavformat/argo_asf.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/argo_asf.c 2022-04-14 21:13:48.000000000 +0100 @@ -422,7 +422,7 @@ ArgoASFMuxContext *ctx = s->priv_data; int64_t ret; - if ((ret = avio_seek(s->pb, ASF_FILE_HEADER_SIZE, SEEK_SET) < 0)) + if ((ret = avio_seek(s->pb, ASF_FILE_HEADER_SIZE, SEEK_SET)) < 0) return ret; avio_wl32(s->pb, (uint32_t)ctx->nb_blocks); diff -Nru ffmpeg-4.4.1/libavformat/avidec.c ffmpeg-4.4.2/libavformat/avidec.c --- ffmpeg-4.4.1/libavformat/avidec.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/avidec.c 2022-04-14 21:13:48.000000000 +0100 @@ -241,6 +241,8 @@ } else { int64_t offset, pos; int duration; + int ret; + offset = avio_rl64(pb); avio_rl32(pb); /* size */ duration = avio_rl32(pb); @@ -258,7 +260,7 @@ if (avio_seek(pb, offset + 8, SEEK_SET) < 0) return -1; avi->odml_depth++; - read_odml_index(s, frame_num); + ret = read_odml_index(s, frame_num); avi->odml_depth--; frame_num += duration; @@ -266,7 +268,8 @@ av_log(s, AV_LOG_ERROR, "Failed to restore position after reading index\n"); return -1; } - + if (ret < 0) + return ret; } } avi->index_loaded = 2; @@ -856,6 +859,8 @@ memcpy(st->codecpar->extradata + st->codecpar->extradata_size - 9, "BottomUp", 9); } + if (st->codecpar->height == INT_MIN) + return AVERROR_INVALIDDATA; st->codecpar->height = FFABS(st->codecpar->height); // avio_skip(pb, size - 5 * 4); diff -Nru ffmpeg-4.4.1/libavformat/cafdec.c ffmpeg-4.4.2/libavformat/cafdec.c --- ffmpeg-4.4.1/libavformat/cafdec.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/cafdec.c 2022-04-14 21:13:48.000000000 +0100 @@ -241,6 +241,8 @@ char value[1024]; avio_get_str(pb, INT_MAX, key, sizeof(key)); avio_get_str(pb, INT_MAX, value, sizeof(value)); + if (!*key) + continue; av_dict_set(&s->metadata, key, value, 0); } } diff -Nru ffmpeg-4.4.1/libavformat/cafenc.c ffmpeg-4.4.2/libavformat/cafenc.c --- ffmpeg-4.4.1/libavformat/cafenc.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/cafenc.c 2022-04-14 21:13:38.000000000 +0100 @@ -28,7 +28,6 @@ typedef struct { int64_t data; - uint8_t *pkt_sizes; int size_buffer_size; int size_entries_used; int packets; @@ -209,30 +208,29 @@ static int caf_write_packet(AVFormatContext *s, AVPacket *pkt) { CAFContext *caf = s->priv_data; + AVStream *const st = s->streams[0]; - avio_write(s->pb, pkt->data, pkt->size); - if (!s->streams[0]->codecpar->block_align) { - void *pkt_sizes = caf->pkt_sizes; - int i, alloc_size = caf->size_entries_used + 5; - if (alloc_size < 0) { - caf->pkt_sizes = NULL; - } else { - caf->pkt_sizes = av_fast_realloc(caf->pkt_sizes, - &caf->size_buffer_size, - alloc_size); - } - if (!caf->pkt_sizes) { - av_free(pkt_sizes); + if (!st->codecpar->block_align) { + uint8_t *pkt_sizes; + int i, alloc_size = caf->size_entries_used + 5U; + if (alloc_size < 0) + return AVERROR(ERANGE); + + pkt_sizes = av_fast_realloc(st->priv_data, + &caf->size_buffer_size, + alloc_size); + if (!pkt_sizes) return AVERROR(ENOMEM); - } + st->priv_data = pkt_sizes; for (i = 4; i > 0; i--) { unsigned top = pkt->size >> i * 7; if (top) - caf->pkt_sizes[caf->size_entries_used++] = 128 | top; + pkt_sizes[caf->size_entries_used++] = 128 | top; } - caf->pkt_sizes[caf->size_entries_used++] = pkt->size & 127; + pkt_sizes[caf->size_entries_used++] = pkt->size & 127; caf->packets++; } + avio_write(s->pb, pkt->data, pkt->size); return 0; } @@ -240,7 +238,8 @@ { CAFContext *caf = s->priv_data; AVIOContext *pb = s->pb; - AVCodecParameters *par = s->streams[0]->codecpar; + AVStream *st = s->streams[0]; + AVCodecParameters *par = st->codecpar; if (pb->seekable & AVIO_SEEKABLE_NORMAL) { int64_t file_size = avio_tell(pb); @@ -250,16 +249,14 @@ avio_seek(pb, file_size, SEEK_SET); if (!par->block_align) { ffio_wfourcc(pb, "pakt"); - avio_wb64(pb, caf->size_entries_used + 24); + avio_wb64(pb, caf->size_entries_used + 24U); avio_wb64(pb, caf->packets); ///< mNumberPackets avio_wb64(pb, caf->packets * samples_per_packet(par->codec_id, par->channels, par->block_align)); ///< mNumberValidFrames avio_wb32(pb, 0); ///< mPrimingFrames avio_wb32(pb, 0); ///< mRemainderFrames - avio_write(pb, caf->pkt_sizes, caf->size_entries_used); - caf->size_buffer_size = 0; + avio_write(pb, st->priv_data, caf->size_entries_used); } } - av_freep(&caf->pkt_sizes); return 0; } diff -Nru ffmpeg-4.4.1/libavformat/flvdec.c ffmpeg-4.4.2/libavformat/flvdec.c --- ffmpeg-4.4.1/libavformat/flvdec.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/flvdec.c 2022-04-14 21:13:48.000000000 +0100 @@ -459,6 +459,8 @@ d = av_int2double(avio_rb64(ioc)); if (isnan(d) || d < INT64_MIN || d > INT64_MAX) goto invalid; + if (current_array == × && (d <= INT64_MIN / 1000 || d >= INT64_MAX / 1000)) + goto invalid; current_array[0][i] = d; } if (times && filepositions) { diff -Nru ffmpeg-4.4.1/libavformat/hls.c ffmpeg-4.4.2/libavformat/hls.c --- ffmpeg-4.4.1/libavformat/hls.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/hls.c 2022-04-14 21:13:48.000000000 +0100 @@ -810,10 +810,16 @@ &info); new_rendition(c, &info, url); } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) { + int64_t t; ret = ensure_playlist(c, &pls, url); if (ret < 0) goto fail; - pls->target_duration = strtoll(ptr, NULL, 10) * AV_TIME_BASE; + t = strtoll(ptr, NULL, 10); + if (t < 0 || t >= INT64_MAX / AV_TIME_BASE) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + pls->target_duration = t * AV_TIME_BASE; } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) { uint64_t seq_no; ret = ensure_playlist(c, &pls, url); @@ -903,7 +909,7 @@ if (has_iv) { memcpy(seg->iv, iv, sizeof(iv)); } else { - int64_t seq = pls->start_seq_no + pls->n_segments; + uint64_t seq = pls->start_seq_no + (uint64_t)pls->n_segments; memset(seg->iv, 0, sizeof(seg->iv)); AV_WB64(seg->iv + 8, seq); } diff -Nru ffmpeg-4.4.1/libavformat/jacosubenc.c ffmpeg-4.4.2/libavformat/jacosubenc.c --- ffmpeg-4.4.1/libavformat/jacosubenc.c 2021-10-21 18:06:35.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/jacosubenc.c 2022-04-14 21:13:38.000000000 +0100 @@ -24,7 +24,7 @@ const AVCodecParameters *par = s->streams[0]->codecpar; if (par->extradata_size) { - avio_write(s->pb, par->extradata, par->extradata_size - 1); + avio_write(s->pb, par->extradata, par->extradata_size); } return 0; } diff -Nru ffmpeg-4.4.1/libavformat/matroskadec.c ffmpeg-4.4.2/libavformat/matroskadec.c --- ffmpeg-4.4.1/libavformat/matroskadec.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/matroskadec.c 2022-04-14 21:13:48.000000000 +0100 @@ -1690,7 +1690,7 @@ case MATROSKA_TRACK_ENCODING_COMP_ZLIB: { z_stream zstream = { 0 }; - if (inflateInit(&zstream) != Z_OK) + if (!pkt_size || inflateInit(&zstream) != Z_OK) return -1; zstream.next_in = data; zstream.avail_in = isize; @@ -1723,7 +1723,7 @@ case MATROSKA_TRACK_ENCODING_COMP_BZLIB: { bz_stream bzstream = { 0 }; - if (BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK) + if (!pkt_size || BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK) return -1; bzstream.next_in = data; bzstream.avail_in = isize; @@ -2806,7 +2806,7 @@ &st->sample_aspect_ratio.den, st->codecpar->height * track->video.display_width * display_width_mul, st->codecpar->width * track->video.display_height * display_height_mul, - 255); + INT_MAX); } if (st->codecpar->codec_id != AV_CODEC_ID_HEVC) st->need_parsing = AVSTREAM_PARSE_HEADERS; @@ -2975,6 +2975,8 @@ if (!matroska->time_scale) matroska->time_scale = 1000000; + if (isnan(matroska->duration)) + matroska->duration = 0; if (matroska->duration) matroska->ctx->duration = matroska->duration * matroska->time_scale * 1000 / AV_TIME_BASE; @@ -3935,7 +3937,9 @@ int i; int nb_index_entries = s->streams[0]->nb_index_entries; AVIndexEntry *index_entries = s->streams[0]->index_entries; - if (ts >= matroska->duration * matroska->time_scale) return (CueDesc) {-1, -1, -1, -1}; + + if (ts >= (int64_t)(matroska->duration * matroska->time_scale)) + return (CueDesc) {-1, -1, -1, -1}; for (i = 1; i < nb_index_entries; i++) { if (index_entries[i - 1].timestamp * matroska->time_scale <= ts && index_entries[i].timestamp * matroska->time_scale > ts) { @@ -4124,6 +4128,8 @@ // prebuffered. pre_bytes = desc_end.end_offset - desc_end.start_offset; pre_ns = desc_end.end_time_ns - desc_end.start_time_ns; + if (pre_ns <= 0) + return -1; pre_sec = pre_ns / nano_seconds_per_second; prebuffer_bytes += pre_bytes * ((temp_prebuffer_ns / nano_seconds_per_second) / pre_sec); @@ -4135,12 +4141,16 @@ 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 = desc_ns / nano_seconds_per_second; - double calc_bits_per_second = (desc_bytes * 8) / desc_sec; + double desc_sec, calc_bits_per_second, percent, mod_bits_per_second; + if (desc_bytes <= 0) + return -1; + + desc_sec = desc_ns / nano_seconds_per_second; + calc_bits_per_second = (desc_bytes * 8) / desc_sec; // Drop the bps by the percentage of bytes buffered. - double percent = (desc_bytes - prebuffer_bytes) / desc_bytes; - double mod_bits_per_second = calc_bits_per_second * percent; + percent = (desc_bytes - prebuffer_bytes) / desc_bytes; + mod_bits_per_second = calc_bits_per_second * percent; if (prebuffer < desc_sec) { double search_sec = diff -Nru ffmpeg-4.4.1/libavformat/moflex.c ffmpeg-4.4.2/libavformat/moflex.c --- ffmpeg-4.4.1/libavformat/moflex.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/moflex.c 2022-04-14 21:13:38.000000000 +0100 @@ -172,7 +172,7 @@ unsigned type, ssize, codec_id = 0; unsigned codec_type, width = 0, height = 0, sample_rate = 0, channels = 0; int stream_index = -1; - AVRational fps; + AVRational tb = av_make_q(0, 1); read_var_byte(s, &type); read_var_byte(s, &ssize); @@ -195,6 +195,7 @@ return AVERROR_PATCHWELCOME; } sample_rate = avio_rb24(pb) + 1; + tb = av_make_q(1, sample_rate); channels = avio_r8(pb) + 1; break; case 1: @@ -208,8 +209,8 @@ av_log(s, AV_LOG_ERROR, "Unsupported video codec: %d\n", codec_id); return AVERROR_PATCHWELCOME; } - fps.num = avio_rb16(pb); - fps.den = avio_rb16(pb); + tb.den = avio_rb16(pb); + tb.num = avio_rb16(pb); width = avio_rb16(pb); height = avio_rb16(pb); avio_skip(pb, type == 3 ? 3 : 2); @@ -237,10 +238,8 @@ if (!st->priv_data) return AVERROR(ENOMEM); - if (sample_rate) - avpriv_set_pts_info(st, 63, 1, sample_rate); - else - avpriv_set_pts_info(st, 63, fps.den, fps.num); + if (tb.num) + avpriv_set_pts_info(st, 63, tb.num, tb.den); } } diff -Nru ffmpeg-4.4.1/libavformat/mov.c ffmpeg-4.4.2/libavformat/mov.c --- ffmpeg-4.4.1/libavformat/mov.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/mov.c 2022-04-14 21:13:48.000000000 +0100 @@ -607,11 +607,13 @@ for (i = 0; i < entries; i++) { MOVDref *dref = &sc->drefs[i]; uint32_t size = avio_rb32(pb); - int64_t next = avio_tell(pb) + size - 4; + int64_t next = avio_tell(pb); - if (size < 12) + if (size < 12 || next < 0 || next > INT64_MAX - size) return AVERROR_INVALIDDATA; + next += size - 4; + dref->type = avio_rl32(pb); avio_rb32(pb); // version + flags @@ -1942,6 +1944,8 @@ // wrap a whole fiel atom inside of a glbl atom. unsigned size = avio_rb32(pb); unsigned type = avio_rl32(pb); + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; avio_seek(pb, -8, SEEK_CUR); if (type == MKTAG('f','i','e','l') && size == atom.size) return mov_read_default(c, pb, atom); @@ -2551,6 +2555,10 @@ av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate); return AVERROR_INVALIDDATA; } + if (st->codecpar->channels < 0) { + av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->channels); + return AVERROR_INVALIDDATA; + } } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){ mov_parse_stsd_subtitle(c, pb, st, sc, size - (avio_tell(pb) - start_pos)); @@ -5116,6 +5124,8 @@ avio_rb16(pb); // reserved item_count = avio_rb16(pb); + if (item_count == 0) + return AVERROR_INVALIDDATA; for (i = 0; i < item_count; i++) { int index; @@ -5441,6 +5451,9 @@ av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version); return 0; } + if (sc->mastering) + return AVERROR_INVALIDDATA; + avio_skip(pb, 3); /* flags */ sc->mastering = av_mastering_display_metadata_alloc(); @@ -6129,6 +6142,8 @@ } if (pb->eof_reached) { av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n"); + if (ret >= 0) + av_encryption_info_free(encryption_index->encrypted_samples[i]); ret = AVERROR_INVALIDDATA; } @@ -7067,6 +7082,8 @@ if (a.size == 0) { a.size = atom.size - total_size + 8; } + if (a.size < 0) + break; a.size -= 8; if (a.size < 0) break; diff -Nru ffmpeg-4.4.1/libavformat/movenc.c ffmpeg-4.4.2/libavformat/movenc.c --- ffmpeg-4.4.1/libavformat/movenc.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/movenc.c 2022-04-14 21:13:38.000000000 +0100 @@ -91,7 +91,7 @@ { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, { "min_frag_duration", "Minimum fragment duration", offsetof(MOVMuxContext, min_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, - { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, + { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 255, AV_OPT_FLAG_ENCODING_PARAM}, { "video_track_timescale", "set timescale of all video tracks", offsetof(MOVMuxContext, video_track_timescale), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, { "brand", "Override major brand", offsetof(MOVMuxContext, major_brand), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM }, { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM}, diff -Nru ffmpeg-4.4.1/libavformat/mxfdec.c ffmpeg-4.4.2/libavformat/mxfdec.c --- ffmpeg-4.4.1/libavformat/mxfdec.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/mxfdec.c 2022-04-14 21:13:48.000000000 +0100 @@ -875,15 +875,27 @@ static int mxf_read_strong_ref_array(AVIOContext *pb, UID **refs, int *count) { - *count = avio_rb32(pb); + int64_t ret; + unsigned c = avio_rb32(pb); + + //avio_read() used int + if (c > INT_MAX / sizeof(UID)) + return AVERROR_PATCHWELCOME; + *count = c; + av_free(*refs); - *refs = av_calloc(*count, sizeof(UID)); + *refs = av_malloc_array(*count, sizeof(UID)); if (!*refs) { *count = 0; return AVERROR(ENOMEM); } avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */ - avio_read(pb, (uint8_t *)*refs, *count * sizeof(UID)); + ret = avio_read(pb, (uint8_t *)*refs, *count * sizeof(UID)); + if (ret != *count * sizeof(UID)) { + *count = ret < 0 ? 0 : ret / sizeof(UID); + return ret < 0 ? ret : AVERROR_INVALIDDATA; + } + return 0; } @@ -1092,6 +1104,9 @@ { int i, length; + if (segment->temporal_offset_entries) + return AVERROR_INVALIDDATA; + segment->nb_index_entries = avio_rb32(pb); length = avio_rb32(pb); @@ -2253,12 +2268,12 @@ /* CDCI range metadata */ if (!descriptor->component_depth) return AVCOL_RANGE_UNSPECIFIED; - if (descriptor->black_ref_level == 0 && + if (descriptor->black_ref_level == 0 && descriptor->component_depth < 31 && descriptor->white_ref_level == ((1<component_depth) - 1) && (descriptor->color_range == (1<component_depth) || descriptor->color_range == ((1<component_depth) - 1))) return AVCOL_RANGE_JPEG; - if (descriptor->component_depth >= 8 && + if (descriptor->component_depth >= 8 && descriptor->component_depth < 31 && descriptor->black_ref_level == (1 <<(descriptor->component_depth - 4)) && descriptor->white_ref_level == (235<<(descriptor->component_depth - 8)) && descriptor->color_range == ((14<<(descriptor->component_depth - 4)) + 1)) diff -Nru ffmpeg-4.4.1/libavformat/omadec.c ffmpeg-4.4.2/libavformat/omadec.c --- ffmpeg-4.4.1/libavformat/omadec.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/omadec.c 2022-04-14 21:13:38.000000000 +0100 @@ -494,7 +494,7 @@ AV_WL16(&edata[6], jsflag); // coding mode AV_WL16(&edata[8], jsflag); // coding mode AV_WL16(&edata[10], 1); // always 1 - // AV_WL16(&edata[12], 0); // always 0 + AV_WL16(&edata[12], 0); // always 0 avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); break; diff -Nru ffmpeg-4.4.1/libavformat/rmdec.c ffmpeg-4.4.2/libavformat/rmdec.c --- ffmpeg-4.4.1/libavformat/rmdec.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/rmdec.c 2022-04-14 21:13:48.000000000 +0100 @@ -128,10 +128,6 @@ uint32_t version; int ret; - // Duplicate tags - if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) - return AVERROR_INVALIDDATA; - /* ra type header */ version = avio_rb16(pb); /* version */ if (version == 3) { @@ -331,6 +327,11 @@ if (codec_data_size == 0) return 0; + // Duplicate tags + if ( st->codecpar->codec_type != AVMEDIA_TYPE_UNKNOWN + && st->codecpar->codec_type != AVMEDIA_TYPE_DATA) + return AVERROR_INVALIDDATA; + avpriv_set_pts_info(st, 64, 1, 1000); codec_pos = avio_tell(pb); v = avio_rb32(pb); diff -Nru ffmpeg-4.4.1/libavformat/sccdec.c ffmpeg-4.4.2/libavformat/sccdec.c --- ffmpeg-4.4.1/libavformat/sccdec.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/sccdec.c 2022-04-14 21:13:38.000000000 +0100 @@ -63,8 +63,7 @@ { SCCContext *scc = s->priv_data; AVStream *st = avformat_new_stream(s, NULL); - char line2[4096], line[4096]; - int64_t pos, ts, next_ts = AV_NOPTS_VALUE; + AVPacket *sub = NULL; ptrdiff_t len; uint8_t out[4096]; FFTextReader tr; @@ -77,47 +76,26 @@ st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codecpar->codec_id = AV_CODEC_ID_EIA_608; - while (!ff_text_eof(&tr) || next_ts == AV_NOPTS_VALUE || line2[0]) { + while (1) { char *saveptr = NULL, *lline; int hh, mm, ss, fs, i; - AVPacket *sub; + char line[4096]; + int64_t pos, ts; - if (next_ts == AV_NOPTS_VALUE) { - while (!ff_text_eof(&tr)) { - len = ff_subtitles_read_line(&tr, line, sizeof(line)); - if (len <= 13) - continue; + len = ff_subtitles_read_line(&tr, line, sizeof(line)); + if (len <= 13) { + if (ff_text_eof(&tr)) + break; + continue; + } if (!strncmp(line, "Scenarist_SCC V1.0", 18)) continue; - if (av_sscanf(line, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4) - break; - } - - ts = (hh * 3600LL + mm * 60LL + ss) * 1000LL + fs * 33LL; - - while (!ff_text_eof(&tr)) { - len = ff_subtitles_read_line(&tr, line2, sizeof(line2)); - if (len <= 13) - continue; - - if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4) - break; - } - } else { - memmove(line, line2, sizeof(line)); - line2[0] = 0; - - while (!ff_text_eof(&tr)) { - len = ff_subtitles_read_line(&tr, line2, sizeof(line2)); - if (len <= 13) - continue; - - if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4) - break; - } - } + if (av_sscanf(line, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) != 4) + continue; - next_ts = (hh * 3600LL + mm * 60LL + ss) * 1000LL + fs * 33LL; + ts = (hh * 3600LL + mm * 60LL + ss) * 1000LL + fs * 33LL; + if (sub) + sub->duration = ts - sub->pts; pos = ff_text_pos(&tr); lline = (char *)&line; @@ -168,8 +146,6 @@ sub->pos = pos; sub->pts = ts; - sub->duration = next_ts - ts; - ts = next_ts; } ff_subtitles_queue_finalize(s, &scc->q); diff -Nru ffmpeg-4.4.1/libavformat/subtitles.c ffmpeg-4.4.2/libavformat/subtitles.c --- ffmpeg-4.4.1/libavformat/subtitles.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/subtitles.c 2022-04-14 21:13:38.000000000 +0100 @@ -418,6 +418,7 @@ size_t cur = 0; if (!size) return 0; + buf[0] = '\0'; while (cur + 1 < size) { unsigned char c = ff_text_r8(tr); if (!c) diff -Nru ffmpeg-4.4.1/libavformat/tee.c ffmpeg-4.4.2/libavformat/tee.c --- ffmpeg-4.4.1/libavformat/tee.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/tee.c 2022-04-14 21:13:38.000000000 +0100 @@ -124,6 +124,7 @@ unsigned i; int ret = 0; + av_dict_free(&tee_slave->fifo_options); avf = tee_slave->avf; if (!avf) return 0; @@ -229,6 +230,7 @@ av_dict_free(&options); options = tee_slave->fifo_options; + tee_slave->fifo_options = NULL; } ret = avformat_alloc_output_context2(&avf2, NULL, tee_slave->use_fifo ? "fifo" :format, filename); @@ -403,6 +405,8 @@ av_free(format); av_free(select); av_free(on_fail); + av_free(use_fifo); + av_free(fifo_options_str); av_dict_free(&options); av_dict_free(&bsf_options); av_freep(&tmp_select); diff -Nru ffmpeg-4.4.1/libavformat/udp.c ffmpeg-4.4.2/libavformat/udp.c --- ffmpeg-4.4.1/libavformat/udp.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/udp.c 2022-04-14 21:13:38.000000000 +0100 @@ -740,8 +740,10 @@ /* XXX: fix av_url_split */ if (hostname[0] == '\0' || hostname[0] == '?') { /* only accepts null hostname if input */ - if (!(flags & AVIO_FLAG_READ)) + if (!(flags & AVIO_FLAG_READ)) { + ret = AVERROR(EINVAL); goto fail; + } } else { if ((ret = ff_udp_set_remote_url(h, uri)) < 0) goto fail; @@ -754,8 +756,10 @@ udp_fd = udp_socket_create(h, &my_addr, &len, localaddr); else udp_fd = udp_socket_create(h, &my_addr, &len, s->localaddr); - if (udp_fd < 0) + if (udp_fd < 0) { + ret = AVERROR(EIO); goto fail; + } s->local_addr_storage=my_addr; //store for future multicast join diff -Nru ffmpeg-4.4.1/libavformat/utils.c ffmpeg-4.4.2/libavformat/utils.c --- ffmpeg-4.4.1/libavformat/utils.c 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/utils.c 2022-04-14 21:13:48.000000000 +0100 @@ -4997,7 +4997,7 @@ key_len = ptr - key; callback_get_buf(context, key, key_len, &dest, &dest_len); - dest_end = dest + dest_len - 1; + dest_end = dest ? dest + dest_len - 1 : NULL; if (*ptr == '\"') { ptr++; diff -Nru ffmpeg-4.4.1/libavformat/vivo.c ffmpeg-4.4.2/libavformat/vivo.c --- ffmpeg-4.4.1/libavformat/vivo.c 2021-10-21 18:06:35.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/vivo.c 2022-04-14 21:13:48.000000000 +0100 @@ -26,6 +26,7 @@ * @sa http://wiki.multimedia.cx/index.php?title=Vivo */ +#include "libavutil/avstring.h" #include "libavutil/parseutils.h" #include "avformat.h" #include "internal.h" @@ -120,7 +121,7 @@ static int vivo_read_header(AVFormatContext *s) { VivoContext *vivo = s->priv_data; - AVRational fps = { 1, 25}; + AVRational fps = { 0 }; AVStream *ast, *vst; unsigned char *line, *line_end, *key, *value; long value_int; @@ -206,17 +207,21 @@ return AVERROR_INVALIDDATA; value_used = 1; } else if (!strcmp(key, "FPS")) { - AVRational tmp; + double d; + if (av_sscanf(value, "%f", &d) != 1) + return AVERROR_INVALIDDATA; value_used = 1; - if (!av_parse_ratio(&tmp, value, 10000, AV_LOG_WARNING, s)) - fps = av_inv_q(tmp); + if (!fps.num && !fps.den) + fps = av_inv_q(av_d2q(d, 10000)); } if (!value_used) av_dict_set(&s->metadata, key, value, 0); } } + if (!fps.num || !fps.den) + fps = (AVRational){ 1, 25 }; avpriv_set_pts_info(ast, 64, 1, ast->codecpar->sample_rate); avpriv_set_pts_info(vst, 64, fps.num, fps.den); diff -Nru ffmpeg-4.4.1/libavformat/webmdashenc.c ffmpeg-4.4.2/libavformat/webmdashenc.c --- ffmpeg-4.4.1/libavformat/webmdashenc.c 2021-10-24 21:47:07.000000000 +0100 +++ ffmpeg-4.4.2/libavformat/webmdashenc.c 2022-04-14 21:13:48.000000000 +0100 @@ -93,7 +93,7 @@ } avio_printf(pb, " minBufferTime=\"PT%gS\"\n", min_buffer_time); avio_printf(pb, " profiles=\"%s\"%s", - w->is_live ? "urn:mpeg:dash:profile:isoff-live:2011" : "urn:webm:dash:profile:webm-on-demand:2012", + w->is_live ? "urn:mpeg:dash:profile:isoff-live:2011" : "urn:mpeg:dash:profile:webm-on-demand:2012", w->is_live ? "\n" : ">\n"); if (w->is_live) { time_t local_time = time(NULL); diff -Nru ffmpeg-4.4.1/libavutil/utils.c ffmpeg-4.4.2/libavutil/utils.c --- ffmpeg-4.4.1/libavutil/utils.c 2021-10-21 18:06:35.000000000 +0100 +++ ffmpeg-4.4.2/libavutil/utils.c 2022-01-14 18:45:25.000000000 +0000 @@ -37,10 +37,6 @@ unsigned avutil_version(void) { - static int checks_done; - if (checks_done) - return LIBAVUTIL_VERSION_INT; - av_assert0(AV_SAMPLE_FMT_DBLP == 9); av_assert0(AVMEDIA_TYPE_ATTACHMENT == 4); av_assert0(AV_PICTURE_TYPE_BI == 7); @@ -58,7 +54,6 @@ av_log(NULL, AV_LOG_ERROR, "Libavutil has been linked to a broken llrint()\n"); } - checks_done = 1; return LIBAVUTIL_VERSION_INT; } diff -Nru ffmpeg-4.4.1/RELEASE ffmpeg-4.4.2/RELEASE --- ffmpeg-4.4.1/RELEASE 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/RELEASE 2022-04-14 21:13:48.000000000 +0100 @@ -1 +1 @@ -4.4.1 +4.4.2 diff -Nru ffmpeg-4.4.1/tests/ref/fate/webm-dash-manifest ffmpeg-4.4.2/tests/ref/fate/webm-dash-manifest --- ffmpeg-4.4.1/tests/ref/fate/webm-dash-manifest 2020-04-27 22:48:16.000000000 +0100 +++ ffmpeg-4.4.2/tests/ref/fate/webm-dash-manifest 2022-04-14 21:13:48.000000000 +0100 @@ -6,7 +6,7 @@ type="static" mediaPresentationDuration="PT32.501S" minBufferTime="PT1S" - profiles="urn:webm:dash:profile:webm-on-demand:2012"> + profiles="urn:mpeg:dash:profile:webm-on-demand:2012"> diff -Nru ffmpeg-4.4.1/tests/ref/fate/webm-dash-manifest-representations ffmpeg-4.4.2/tests/ref/fate/webm-dash-manifest-representations --- ffmpeg-4.4.1/tests/ref/fate/webm-dash-manifest-representations 2020-04-27 22:48:16.000000000 +0100 +++ ffmpeg-4.4.2/tests/ref/fate/webm-dash-manifest-representations 2022-04-14 21:13:48.000000000 +0100 @@ -6,7 +6,7 @@ type="static" mediaPresentationDuration="PT32.48S" minBufferTime="PT1S" - profiles="urn:webm:dash:profile:webm-on-demand:2012"> + profiles="urn:mpeg:dash:profile:webm-on-demand:2012"> diff -Nru ffmpeg-4.4.1/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams ffmpeg-4.4.2/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams --- ffmpeg-4.4.1/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams 2020-04-27 22:48:16.000000000 +0100 +++ ffmpeg-4.4.2/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams 2022-04-14 21:13:48.000000000 +0100 @@ -6,7 +6,7 @@ type="static" mediaPresentationDuration="PT32.501S" minBufferTime="PT1S" - profiles="urn:webm:dash:profile:webm-on-demand:2012"> + profiles="urn:mpeg:dash:profile:webm-on-demand:2012"> diff -Nru ffmpeg-4.4.1/tests/ref/fate/webm-dash-manifest-unaligned-video-streams ffmpeg-4.4.2/tests/ref/fate/webm-dash-manifest-unaligned-video-streams --- ffmpeg-4.4.1/tests/ref/fate/webm-dash-manifest-unaligned-video-streams 2020-04-27 22:48:16.000000000 +0100 +++ ffmpeg-4.4.2/tests/ref/fate/webm-dash-manifest-unaligned-video-streams 2022-04-14 21:13:48.000000000 +0100 @@ -6,7 +6,7 @@ type="static" mediaPresentationDuration="PT32.48S" minBufferTime="PT1S" - profiles="urn:webm:dash:profile:webm-on-demand:2012"> + profiles="urn:mpeg:dash:profile:webm-on-demand:2012"> diff -Nru ffmpeg-4.4.1/VERSION ffmpeg-4.4.2/VERSION --- ffmpeg-4.4.1/VERSION 2021-10-24 21:47:11.000000000 +0100 +++ ffmpeg-4.4.2/VERSION 2022-04-14 21:13:48.000000000 +0100 @@ -1 +1 @@ -4.4.1 +4.4.2