Compare commits

..

20 commits

Author SHA1 Message Date
Manuel Lauss
0226b6fb2c avcodec/sanm: bl16: fix artifacts in larger videos
Some checks failed
/ lint (push) Has been cancelled
/ run_fate (linux-aarch64) (push) Has been cancelled
/ run_fate (linux-amd64) (push) Has been cancelled
/ compile_only (ghcr.io/btbn/ffmpeg-builds/win64-gpl:latest) (push) Has been cancelled
The DOS/Windows decoder precomputes a table of linear offsets of
all motion vectors given the current image width.
For larger widths (>=762), the pairs starting at indices 1 and 254
of motion_vectors[] will overflow the int16_t, changing the sign.

Playing back the 800x600 "jonesopn_8.snm" video of "Indiana Jones and
the Infernal Machine" reveals a lot of artifacts and a lot of
"Ignoring invalid motion vector (149, -41)->(136, 0), block size = 8"
messages, hinting at the wrong direction of the motion vectors.

Fix this by doing the calculation that the DOS/Windows players do,
let the value overflow and reextract the "new" mvec x/y components.
2025-08-18 09:11:09 +00:00
Valerii Zapodovnikov
8426622bb9 avformat/avio: clarify that AVSEEK_FORCE has no effect
avio_seek() never supported SEEK_END and returned AVERROR(EINVAL) when
specified, so the later check "(whence != SEEK_END || force)" was always true.

This also means that AVSEEK_FORCE had no effect since 7a6fe01f99, that is 15
years ago. Rather than changing behaviour, let's document instead that the flag
has no effect.

Also fixed other commit 41ed7ab45f which confused ORing / passing AVSEEK_FORCE
and AVSEEK_SIZE in the docs.

Signed-off-by: Valerii Zapodovnikov <val.zapod.vz@gmail.com>
2025-08-17 20:47:11 +00:00
Michael Niedermayer
134fbfd1dc
avcodec/sanm: Check w,h,left,top
The setup code fow w,h,left,top is complex, the code using it also falls in
at least 2 different classes, one using left/top the other not.

To ensure no out of array access happens we add this clear check.

Fixes: out of array access
Fixes: 439261995/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_SANM_fuzzer-5383455572819968

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2025-08-17 15:39:33 +02:00
James Almer
a2cfaf1b91 avformat/mov: pass stream index to sanity_checks on HEIF images
Instead of item_id. Same behavior as with standard video tracks.

Signed-off-by: James Almer <jamrial@gmail.com>
2025-08-16 21:59:18 -03:00
James Almer
a28e01a6c1 avformat/mov: don't use an allocated array for sample_size with HEIF images
The array is only ever needed for streams where each sample entry may have a
different value. Given that for non animated HEIF there's a single value that
applies to the image, use the field defined for that.

Fixes: NULL pointer dereference
Fixes: 437528618/clusterfuzz-testcase-minimized-ffmpeg_dem_MOV_fuzzer-6537287645331456

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: James Almer <jamrial@gmail.com>
2025-08-16 21:59:18 -03:00
Gyan Doshi
7df9271272 avfilter/whisper: correct option formatting 2025-08-17 00:58:03 +00:00
Zhao Zhili
1d06e8ddcd avfilter/af_whisper: fix broken output for multibyte character
text + 1 can break a multibyte character, e.g., Chinese in UTF-8.
There is no space at the beginning in this case.
2025-08-16 13:58:14 +00:00
Leo Izen
30e6956920
.forgejo/CODEOWNERS: add myself to JPEG XL and PNG
Add myself to JPEG XL and PNG decoders/encoders/parsers/etc. as a
suggested reviewer. I'm the maintainer of the JXL files and I know the
PNG code very well.

Signed-off-by: Leo Izen <leo.izen@gmail.com>
2025-08-16 05:07:19 -04:00
Jack Lau
37507c6a78 avformat/whip: remove DTLSState enum
This patch aims to simplify the dtls handshake process
since dtls handshake use force block mode

We can just use the return code instead of DTLSState enum

Signed-off-by: Jack Lau <jacklau1222@qq.com>
2025-08-16 06:25:04 +00:00
Michael Niedermayer
50affd2b09 avcodec/rv60dec: clear pu_info
pu_info is read uninitialized on damaged input and at that point the following codepath is dependant
on the uninitialized data. In one of these pathes out of array accesses happen.
None of this is replicatable

Less uninitialized data also should result in more reproducable reports

Fixes: Use of uninitialized memory
Fixes: 418335931/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_RV60_fuzzer-5103986067963904

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2025-08-16 00:24:52 +00:00
Kacper Michajłow
61d0050924 avformat/tls_openssl: simplify fingerprint generation
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
2025-08-16 00:15:30 +00:00
Kacper Michajłow
4676f97928 avformat/tls_openssl: clean keys serialization
It was unnecessary convoluted, remove not needed memory allocations,
snprintf.

Also fixes posibility to call snprinft with NULL as %s input.

Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
2025-08-16 00:15:30 +00:00
Kacper Michajłow
113c9c6cf3 configure: require at least OpenSSL 1.1.1 (LTS)
Commit f256487cd8 bumped requirement to
1.1.0 for OPENSSL_init_ssl.

Bump this again to 1.1.1, because it was an LTS version. Although it has
no mainline support anymore, it still has paid/premium support. 1.1.0 has
no support at all.

Motivated for use of BIO_read_ex() for next commits.

Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
2025-08-16 00:15:30 +00:00
Kacper Michajłow
3a8b3dfeca avformat/tls_openssl: use ascii - (0x2D) instead of 0x2010 hyphen
Too much AI is bad for you...

Fixes: 167e343bbe
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
2025-08-16 00:15:30 +00:00
Kacper Michajłow
1f4fed5cc3 w32pthreads: add support for setting thread name
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
2025-08-15 19:54:01 +00:00
Kacper Michajłow
5ff2500514
avcodec/x86/Makefile: add missing x86/proresdsp.o for prores raw 2025-08-15 20:45:20 +02:00
wangbin
6e48050568 configure: fix -L flags for lld-link 2025-08-15 18:20:33 +00:00
Michael Niedermayer
2a22972db3
avcodec/utvideodec: Clear plane_start array
in pack mode the array is passed into decode_plane() without being initialized or used

Fixes: use of uninitialized memory
Fixes: 438780119/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_UTVIDEO_DEC_fuzzer-5464037027807232

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2025-08-15 18:00:11 +02:00
Oliver Chang
c9e93df4ee avcodec/prores_raw: Fix heap buffer overflow
When dimensions differ from context, those were updated using
ff_set_dimensions, however this overwrote the aligned coded_width and
coded_height that were set before, leading to a buffer overflow when
writing the frame data.

Fixes: OssFuzz 438771336
Fixes: Heap-buffer-overflow

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Marvin Scholz <epirat07@gmail.com>
Reviewed-by: Marvin Scholz <epirat07@gmail.com>
2025-08-15 15:06:58 +00:00
David Rosca
ac5303a5b9 hw_base_encode: Support refs option to limit number of references
Set default value to 0 to keep the old behavior of using maximum number
of references.
2025-08-15 13:55:51 +00:00
29 changed files with 171 additions and 272 deletions

View file

@ -20,9 +20,10 @@ libavcodec/.*ffv1.* @lynne @michaelni
libavcodec/golomb.* @michaelni
libavcodec/.*h266.* @frankplow @NuoMi @jianhuaw
libavcodec/h26x/.* @frankplow @NuoMi @jianhuaw
libavcodec/.*jpegxl.* @lynne
libavcodec/.*jxl.* @lynne
libavcodec/.*jpegxl.* @lynne @Traneptora
libavcodec/.*jxl.* @lynne @Traneptora
libavcodec/.*opus.* @lynne
libavcodec/.*png.* @Traneptora
libavcodec/.*prores.* @lynne
libavcodec/rangecoder.* @michaelni
libavcodec/ratecontrol.* @michaelni
@ -45,6 +46,8 @@ libavfilter/vsrc_mandelbrot.* @michaelni
# avformat
# =======
libavformat/iamf.* @jamrial
libavformat/.*jpegxl.* @Traneptora
libavformat/.*jxl.* @Traneptora
# avutil
# ======

View file

@ -8,6 +8,7 @@ version 8.0:
- Whisper filter
- Drop support for OpenSSL < 1.1.0
- Enable TLS peer certificate verification by default (on next major version bump)
- Drop support for OpenSSL < 1.1.1
- yasm support dropped, users need to use nasm
- VVC VAAPI decoder
- RealVideo 6.0 decoder

View file

@ -44,6 +44,7 @@
#include "libavutil/internal.h"
#include "libavutil/mem.h"
#include "libavutil/time.h"
#include "libavutil/wchar_filename.h"
typedef struct pthread_t {
void *handle;
@ -209,4 +210,38 @@ static inline int pthread_setcancelstate(int state, int *oldstate)
return 0;
}
static inline int win32_thread_setname(const char *name)
{
#if !HAVE_UWP
typedef HRESULT (WINAPI *SetThreadDescriptionFn)(HANDLE, PCWSTR);
// Although SetThreadDescription lives in kernel32.dll, on Windows Server 2016,
// Windows 10 LTSB 2016 and Windows 10 version 1607, it was only available in
// kernelbase.dll. So, load it from there for maximum coverage.
HMODULE kernelbase = GetModuleHandleW(L"kernelbase.dll");
if (!kernelbase)
return AVERROR(ENOSYS);
SetThreadDescriptionFn pSetThreadDescription =
(SetThreadDescriptionFn)GetProcAddress(kernelbase, "SetThreadDescription");
if (!pSetThreadDescription)
return AVERROR(ENOSYS);
wchar_t *wname;
if (utf8towchar(name, &wname) < 0)
return AVERROR(ENOMEM);
HRESULT hr = pSetThreadDescription(GetCurrentThread(), wname);
av_free(wname);
return SUCCEEDED(hr) ? 0 : AVERROR(EINVAL);
#else
// UWP is not supported because we cannot use LoadLibrary/GetProcAddress to
// detect the availability of the SetThreadDescription API. There is a small
// gap in Windows builds 1507-1607 where it was not available. UWP allows
// querying the availability of APIs with QueryOptionalDelayLoadedAPI, but it
// requires /DELAYLOAD:kernel32.dll during linking, and we cannot enforce that.
return AVERROR(ENOSYS);
#endif
}
#endif /* COMPAT_W32PTHREADS_H */

6
configure vendored
View file

@ -5174,7 +5174,7 @@ probe_cc(){
# but we can force it back to gnu mode and get the version from there.
_ident=$($_cc -flavor gnu --version 2>/dev/null)
_ld_o='-out:$@'
_flags_filter=msvc_flags
_flags_filter=msvc_flags_link
_ld_lib='%.lib'
_ld_path='-libpath:'
elif VSLANG=1033 $_cc -nologo- 2>&1 | grep -q ^Microsoft || { $_cc -v 2>&1 | grep -q clang && $_cc -? > /dev/null 2>&1; }; then
@ -7260,10 +7260,10 @@ enabled omx && require_headers OMX_Core.h && \
enabled openssl && { { check_pkg_config openssl "openssl >= 3.0.0" openssl/ssl.h OPENSSL_init_ssl &&
{ enabled gplv3 || ! enabled gpl || enabled nonfree || die "ERROR: OpenSSL >=3.0.0 requires --enable-version3"; }; } ||
{ enabled gpl && ! enabled nonfree && die "ERROR: OpenSSL <3.0.0 is incompatible with the gpl"; } ||
check_pkg_config openssl "openssl >= 1.1.0" openssl/ssl.h OPENSSL_init_ssl ||
check_pkg_config openssl "openssl >= 1.1.1" openssl/ssl.h OPENSSL_init_ssl ||
check_lib openssl openssl/ssl.h OPENSSL_init_ssl -lssl -lcrypto ||
check_lib openssl openssl/ssl.h OPENSSL_init_ssl -lssl -lcrypto -lws2_32 -lgdi32 ||
die "ERROR: openssl (>= 1.1.0) not found"; }
die "ERROR: openssl (>= 1.1.1) not found"; }
enabled pocketsphinx && require_pkg_config pocketsphinx pocketsphinx pocketsphinx/pocketsphinx.h ps_init
enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/rk_mpi.h mpp_create &&
require_pkg_config rockchip_mpp "rockchip_mpp >= 1.3.7" rockchip/rk_mpi.h mpp_create &&

View file

@ -762,6 +762,7 @@ static const FFCodecDefault d3d12va_encode_hevc_defaults[] = {
{ "b_qoffset", "0" },
{ "qmin", "-1" },
{ "qmax", "-1" },
{ "refs", "0" },
{ NULL },
};

View file

@ -666,6 +666,11 @@ int ff_hw_base_init_gop_structure(FFHWBaseEncodeContext *ctx, AVCodecContext *av
ctx->ref_l0 = FFMIN(ref_l0, MAX_PICTURE_REFERENCES);
ctx->ref_l1 = FFMIN(ref_l1, MAX_PICTURE_REFERENCES);
if (avctx->refs > 0) {
ctx->ref_l0 = FFMIN(ctx->ref_l0, avctx->refs);
ctx->ref_l1 = FFMIN(ctx->ref_l1, avctx->refs);
}
if (flags & FF_HW_FLAG_INTRA_ONLY || avctx->gop_size <= 1) {
av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
ctx->gop_size = 1;

View file

@ -29,7 +29,6 @@
#include "libavutil/opt.h"
#include "libavutil/time.h"
#include "codec_internal.h"
#include "profiles.h"
#include "internal.h"
#include "compat/w32dlfcn.h"
#if CONFIG_D3D11VA
@ -712,26 +711,6 @@ static int64_t mf_enca_output_score(AVCodecContext *avctx, IMFMediaType *type)
score |= 4LL << 32;
}
if (avctx->codec_id == AV_CODEC_ID_AAC) {
hr = IMFAttributes_GetUINT32(type, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, &t);
switch (avctx->profile) {
case AV_PROFILE_AAC_LOW:
if (!FAILED(hr) && !(t >= 0x28 && t < 0x2c) && t != 0x50 && t != 0x51)
return -1;
break;
case AV_PROFILE_AAC_HE:
if (!FAILED(hr) && !(t >= 0x2c && t < 0x30) && t != 0x52 && t != 0x53)
return -1;
break;
case AV_PROFILE_AAC_HE_V2:
if (!FAILED(hr) && !(t >= 0x30 && t < 0x34))
return -1;
break;
}
}
// Select the bitrate (lowest priority).
hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &t);
if (!FAILED(hr)) {
@ -1007,32 +986,12 @@ static int mf_choose_output_type(AVCodecContext *avctx)
}
if (ret >= 0) {
unsigned int profile_set;
unsigned int profile_negotiated;
av_log(avctx, AV_LOG_VERBOSE, "setting output type:\n");
ff_media_type_dump(avctx, out_type);
IMFAttributes_GetUINT32(out_type, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, &profile_set);
hr = IMFTransform_SetOutputType(c->mft, c->out_stream_id, out_type, 0);
if (!FAILED(hr)) {
unsigned int bitrate;
IMFAttributes_GetUINT32(out_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &bitrate);
if (avctx->codec_id == AV_CODEC_ID_AAC) {
IMFAttributes_GetUINT32(out_type, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, &profile_negotiated);
if (profile_set != profile_negotiated) { // Setting PROFILE_LEVEL_INDICATION in AAC Encoder is only supported starting from Win11 24H2, fail if reported a mismatch in profile level indication.
av_log(avctx, AV_LOG_ERROR, "profile level indication mismatch: (out_type profile_level) %d != (out_type_negotiated profile_level) %d\n", profile_set, profile_negotiated);
ret = AVERROR_EXTERNAL;
} else {
av_log(avctx, AV_LOG_INFO, "using bitrate %dkbps, profile level: 0x%02x\n", bitrate / 125, profile_set);
ret = 1;
}
} else {
av_log(avctx, AV_LOG_INFO, "using bitrate %dkbps\n", bitrate / 125);
ret = 1;
}
ret = 1;
} else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
av_log(avctx, AV_LOG_VERBOSE, "rejected - need to set input type\n");
ret = 0;
@ -1468,13 +1427,7 @@ static av_cold int mf_init(AVCodecContext *avctx)
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID | \
AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE,
#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption aac_opts[] = {
FF_AAC_PROFILE_OPTS
{NULL}
};
MF_ENCODER(AUDIO, aac, AAC, aac_opts, AFMTS, ACAPS, NULL);
MF_ENCODER(AUDIO, aac, AAC, NULL, AFMTS, ACAPS, NULL);
MF_ENCODER(AUDIO, ac3, AC3, NULL, AFMTS, ACAPS, NULL);
MF_ENCODER(AUDIO, mp3, MP3, NULL, AFMTS, ACAPS, NULL);

View file

@ -367,9 +367,6 @@ static int decode_frame(AVCodecContext *avctx,
if ((w & 1) || (h & 1))
return AVERROR_INVALIDDATA;
avctx->coded_width = FFALIGN(w, 16);
avctx->coded_height = FFALIGN(h, 16);
if (w != avctx->width || h != avctx->height) {
av_log(avctx, AV_LOG_WARNING, "picture resolution change: %ix%i -> %ix%i\n",
avctx->width, avctx->height, w, h);
@ -377,6 +374,9 @@ static int decode_frame(AVCodecContext *avctx,
return ret;
}
avctx->coded_width = FFALIGN(w, 16);
avctx->coded_height = FFALIGN(h, 16);
enum AVPixelFormat pix_fmt = AV_PIX_FMT_BAYER_RGGB16;
if (pix_fmt != s->pix_fmt) {
s->pix_fmt = pix_fmt;

View file

@ -308,6 +308,8 @@ static int update_dimensions_clear_info(RV60Context *s, int width, int height)
if ((ret = av_reallocp_array(&s->blk_info, s->blk_stride * (s->cu_height << 4), sizeof(s->blk_info[0]))) < 0)
return ret;
memset(s->pu_info, 0, s->pu_stride * (s->cu_height << 3) * sizeof(s->pu_info[0]));
for (int j = 0; j < s->cu_height << 4; j++)
for (int i = 0; i < s->cu_width << 4; i++)
s->blk_info[j*s->blk_stride + i].mv.mvref = MVREF_NONE;

View file

@ -1757,6 +1757,11 @@ static int process_frame_obj(SANMVideoContext *ctx, GetByteContext *gb)
memset(ctx->fbuf, 0, ctx->frm0_size);
}
if (w + FFMAX(left, 0) > ctx->avctx->width || h + FFMAX(top, 0) > ctx->avctx->height) {
avpriv_request_sample(ctx->avctx, "overly large frame\n");
return AVERROR_PATCHWELCOME;
}
switch (codec) {
case 1:
case 3:
@ -2069,6 +2074,20 @@ static int codec2subblock(SANMVideoContext *ctx, int cx, int cy, int blk_size)
mx = motion_vectors[opcode][0];
my = motion_vectors[opcode][1];
/* The original implementation of this codec precomputes a table
* of int16_t all motion vectors for given image width.
* For larger widths, starting with 762 pixels, the calculation of
* mv table indices 1+ and 255- overflow the int16_t, inverting the
* sign of the offset. This is actively exploited in e.g. the
* "jonesopn_8.snm" video of "Indiana Jones and the Infernal Machine".
* Therefore let the overflow happen and extract x/y components from
* the new value.
*/
if (ctx->width > 761) {
index = (int16_t)(my * ctx->width + mx);
mx = index % ctx->width;
my = index / ctx->width;
}
if (good_mvec(ctx, cx, cy, mx, my, blk_size)) {
copy_block(ctx->frm0 + cx + ctx->pitch * cy,
ctx->frm2 + cx + mx + ctx->pitch * (cy + my),

View file

@ -585,7 +585,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
int buf_size = avpkt->size;
UtvideoContext *c = avctx->priv_data;
int i, j;
const uint8_t *plane_start[5];
const uint8_t *plane_start[5] = {NULL};
int plane_size, max_slice_size = 0, slice_start, slice_end, slice_size;
int ret;
GetByteContext gb;

View file

@ -1027,6 +1027,7 @@ static const FFCodecDefault vaapi_encode_av1_defaults[] = {
{ "g", "120" },
{ "qmin", "1" },
{ "qmax", "255" },
{ "refs", "0" },
{ NULL },
};

View file

@ -1153,6 +1153,7 @@ static const FFCodecDefault vaapi_encode_h264_defaults[] = {
{ "b_qoffset", "0" },
{ "qmin", "-1" },
{ "qmax", "-1" },
{ "refs", "0" },
{ NULL },
};

View file

@ -1184,6 +1184,7 @@ static const FFCodecDefault vaapi_encode_h265_defaults[] = {
{ "b_qoffset", "0" },
{ "qmin", "-1" },
{ "qmax", "-1" },
{ "refs", "0" },
{ NULL },
};

View file

@ -235,6 +235,7 @@ static const FFCodecDefault vaapi_encode_vp8_defaults[] = {
{ "g", "120" },
{ "qmin", "-1" },
{ "qmax", "-1" },
{ "refs", "0" },
{ NULL },
};

View file

@ -292,6 +292,7 @@ static const FFCodecDefault vaapi_encode_vp9_defaults[] = {
{ "g", "250" },
{ "qmin", "-1" },
{ "qmax", "-1" },
{ "refs", "0" },
{ NULL },
};

View file

@ -1367,6 +1367,7 @@ static const FFCodecDefault vulkan_encode_av1_defaults[] = {
{ "g", "300" },
{ "qmin", "1" },
{ "qmax", "255" },
{ "refs", "0" },
{ NULL },
};

View file

@ -1634,6 +1634,7 @@ static const FFCodecDefault vulkan_encode_h264_defaults[] = {
{ "b_qoffset", "0" },
{ "qmin", "-1" },
{ "qmax", "-1" },
{ "refs", "0" },
{ NULL },
};

View file

@ -1761,6 +1761,7 @@ static const FFCodecDefault vulkan_encode_h265_defaults[] = {
{ "b_qoffset", "0" },
{ "qmin", "-1" },
{ "qmax", "-1" },
{ "refs", "0" },
{ NULL },
};

View file

@ -170,6 +170,7 @@ X86ASM-OBJS-$(CONFIG_MLP_DECODER) += x86/mlpdsp.o
X86ASM-OBJS-$(CONFIG_MPEG4_DECODER) += x86/xvididct.o
X86ASM-OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp.o
X86ASM-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp.o
X86ASM-OBJS-$(CONFIG_PRORES_RAW_DECODER) += x86/proresdsp.o
X86ASM-OBJS-$(CONFIG_RV40_DECODER) += x86/rv40dsp.o
X86ASM-OBJS-$(CONFIG_SBC_ENCODER) += x86/sbcdsp.o
X86ASM-OBJS-$(CONFIG_SVQ1_ENCODER) += x86/svq1enc.o

View file

@ -215,7 +215,9 @@ static void run_transcription(AVFilterContext *ctx, AVFrame *frame, int samples)
for (int i = 0; i < n_segments; ++i) {
const char *text = whisper_full_get_segment_text(wctx->ctx_wsp, i);
char *text_cleaned = av_strireplace(text + 1, "[BLANK_AUDIO]", "");
if (av_isspace(text[0]))
text++;
char *text_cleaned = av_strireplace(text, "[BLANK_AUDIO]", "");
if (av_strnlen(text_cleaned, 1) == 0) {
av_freep(&text_cleaned);
@ -428,7 +430,8 @@ static int query_formats(const AVFilterContext *ctx,
#define HOURS 3600000000
static const AVOption whisper_options[] = {
{ "model", "Path to the whisper.cpp model file", OFFSET(model_path), AV_OPT_TYPE_STRING,.flags = FLAGS }, { "language", "Language for transcription ('auto' for auto-detect)", OFFSET(language), AV_OPT_TYPE_STRING, {.str = "auto"}, .flags = FLAGS },
{ "model", "Path to the whisper.cpp model file", OFFSET(model_path), AV_OPT_TYPE_STRING,.flags = FLAGS },
{ "language", "Language for transcription ('auto' for auto-detect)", OFFSET(language), AV_OPT_TYPE_STRING, {.str = "auto"}, .flags = FLAGS },
{ "queue", "Audio queue size", OFFSET(queue), AV_OPT_TYPE_DURATION, {.i64 = 3000000}, 20000, HOURS, .flags = FLAGS },
{ "use_gpu", "Use GPU for processing", OFFSET(use_gpu), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, .flags = FLAGS },
{ "gpu_device", "GPU device to use", OFFSET(gpu_device), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, .flags = FLAGS },

View file

@ -461,17 +461,17 @@ int avio_put_str16be(AVIOContext *s, const char *str);
void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type);
/**
* ORing this as the "whence" parameter to a seek function causes it to
* Passing this as the "whence" parameter to a seek function causes it to
* return the filesize without seeking anywhere. Supporting this is optional.
* If it is not supported then the seek function will return <0.
*/
#define AVSEEK_SIZE 0x10000
/**
* Passing this flag as the "whence" parameter to a seek function causes it to
* OR'ing this flag into the "whence" parameter to a seek function causes it to
* seek by any means (like reopening and linear reading) or other normally unreasonable
* means that can be extremely slow.
* This may be ignored by the seek code.
* This is the default and therefore ignored by the seek code since 2010.
*/
#define AVSEEK_FORCE 0x20000

View file

@ -238,10 +238,9 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
FFIOContext *const ctx = ffiocontext(s);
int64_t offset1;
int64_t pos;
int force = whence & AVSEEK_FORCE;
int buffer_size;
int short_seek;
whence &= ~AVSEEK_FORCE;
whence &= ~AVSEEK_FORCE; // force flag does nothing
if(!s)
return AVERROR(EINVAL);
@ -282,8 +281,7 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
} else if ((!(s->seekable & AVIO_SEEKABLE_NORMAL) ||
offset1 <= buffer_size + short_seek) &&
!s->write_flag && offset1 >= 0 &&
(!s->direct || !s->seek) &&
(whence != SEEK_END || force)) {
(!s->direct || !s->seek)) {
while(s->pos < offset && !s->eof_reached)
fill_buffer(s);
if (s->eof_reached)
@ -300,7 +298,7 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
s->pos = pos;
s->eof_reached = 0;
fill_buffer(s);
return avio_seek(s, offset, SEEK_SET | force);
return avio_seek(s, offset, SEEK_SET);
} else {
int64_t res;
if (s->write_flag) {

View file

@ -5456,10 +5456,6 @@ static int heif_add_stream(MOVContext *c, HEIFItem *item)
if (!sc->chunk_offsets)
goto fail;
sc->chunk_count = 1;
sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
if (!sc->sample_sizes)
goto fail;
sc->sample_count = 1;
sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
if (!sc->stts_data)
goto fail;
@ -10471,11 +10467,13 @@ static int mov_parse_heif_items(AVFormatContext *s)
st->codecpar->width = item->width;
st->codecpar->height = item->height;
err = sanity_checks(s, sc, item->item_id);
if (err || !sc->sample_count)
sc->sample_size = sc->stsz_sample_size = item->extent_length;
sc->sample_count = 1;
err = sanity_checks(s, sc, st->index);
if (err)
return AVERROR_INVALIDDATA;
sc->sample_sizes[0] = item->extent_length;
sc->chunk_offsets[0] = item->extent_offset + offset;
if (item->item_id == mov->primary_item_id)

View file

@ -34,17 +34,6 @@
*/
#define MAX_CERTIFICATE_SIZE 8192
enum DTLSState {
DTLS_STATE_NONE,
/* Whether DTLS handshake is finished. */
DTLS_STATE_FINISHED,
/* Whether DTLS session is closed. */
DTLS_STATE_CLOSED,
/* Whether DTLS handshake is failed. */
DTLS_STATE_FAILED,
};
typedef struct TLSShared {
char *ca_file;
int verify;
@ -65,8 +54,6 @@ typedef struct TLSShared {
int is_dtls;
int use_srtp;
enum DTLSState state;
/* The certificate and private key content used for DTLS handshake */
char* cert_buf;
char* key_buf;
@ -112,8 +99,6 @@ int ff_tls_set_external_socket(URLContext *h, URLContext *sock);
int ff_dtls_export_materials(URLContext *h, char *dtls_srtp_materials, size_t materials_sz);
int ff_dtls_state(URLContext *h);
int ff_ssl_read_key_cert(char *key_url, char *cert_url, char *key_buf, size_t key_sz, char *cert_buf, size_t cert_sz, char **fingerprint);
int ff_ssl_gen_key_cert(char *key_buf, size_t key_sz, char *cert_buf, size_t cert_sz, char **fingerprint);

View file

@ -35,127 +35,82 @@
#include <openssl/x509v3.h>
/**
* Returns a heapallocated nullterminated string containing
* the PEMencoded public key. Caller must free.
* Convert an EVP_PKEY to a PEM string.
*/
static char *pkey_to_pem_string(EVP_PKEY *pkey) {
BIO *mem = NULL;
BUF_MEM *bptr = NULL;
char *pem_str = NULL;
static int pkey_to_pem_string(EVP_PKEY *pkey, char *out, size_t out_sz)
{
BIO *mem = NULL;
size_t read_bytes = 0;
if (!pkey || !out || !out_sz)
goto done;
// Create a memory BIO
if (!(mem = BIO_new(BIO_s_mem())))
goto err;
goto done;
// Write public key in PEM form
if (!PEM_write_bio_PrivateKey(mem, pkey, NULL, NULL, 0, NULL, NULL))
goto err;
goto done;
// Extract pointer/length
BIO_get_mem_ptr(mem, &bptr);
if (!bptr || !bptr->length)
goto err;
if (!BIO_read_ex(mem, out, out_sz - 1, &read_bytes))
goto done;
// Allocate string (+1 for NUL)
pem_str = av_malloc(bptr->length + 1);
if (!pem_str)
goto err;
// Copy data & NULterminate
memcpy(pem_str, bptr->data, bptr->length);
pem_str[bptr->length] = '\0';
cleanup:
done:
BIO_free(mem);
return pem_str;
err:
// error path: free and return NULL
free(pem_str);
pem_str = NULL;
goto cleanup;
if (out && out_sz)
out[read_bytes] = '\0';
return read_bytes;
}
/**
* Serialize an X509 certificate to a av_mallocd PEM string.
* Caller must free the returned pointer.
* Convert an X509 certificate to a PEM string.
*/
static char *cert_to_pem_string(X509 *cert)
static int cert_to_pem_string(X509 *cert, char *out, size_t out_sz)
{
BIO *mem = BIO_new(BIO_s_mem());
BUF_MEM *bptr = NULL;
char *out = NULL;
BIO *mem = NULL;
size_t read_bytes = 0;
if (!mem) goto err;
if (!cert || !out || !out_sz)
goto done;
if (!(mem = BIO_new(BIO_s_mem())))
goto done;
/* Write the PEM certificate */
if (!PEM_write_bio_X509(mem, cert))
goto err;
goto done;
BIO_get_mem_ptr(mem, &bptr);
if (!bptr || !bptr->length) goto err;
if (!BIO_read_ex(mem, out, out_sz - 1, &read_bytes))
goto done;
out = av_malloc(bptr->length + 1);
if (!out) goto err;
memcpy(out, bptr->data, bptr->length);
out[bptr->length] = '\0';
cleanup:
done:
BIO_free(mem);
return out;
err:
free(out);
out = NULL;
goto cleanup;
if (out && out_sz)
out[read_bytes] = '\0';
return read_bytes;
}
/**
* Generate a SHA-256 fingerprint of an X.509 certificate.
*
* @param ctx AVFormatContext for logging (can be NULL)
* @param cert X509 certificate to fingerprint
* @return Newly allocated fingerprint string in "AA:BB:CC:…" format,
* or NULL on error (logs via av_log if ctx is not NULL).
* Caller must free() the returned string.
*/
static char *generate_fingerprint(X509 *cert)
static int x509_fingerprint(X509 *cert, char **fingerprint)
{
unsigned char md[EVP_MAX_MD_SIZE];
int n = 0;
AVBPrint fingerprint;
char *result = NULL;
int i;
/* To prevent a crash during cleanup, always initialize it. */
av_bprint_init(&fingerprint, 0, AV_BPRINT_SIZE_UNLIMITED);
AVBPrint buf;
if (X509_digest(cert, EVP_sha256(), md, &n) != 1) {
av_log(NULL, AV_LOG_ERROR, "TLS: Failed to generate fingerprint, %s\n", ERR_error_string(ERR_get_error(), NULL));
goto end;
av_log(NULL, AV_LOG_ERROR, "TLS: Failed to generate fingerprint, %s\n",
ERR_error_string(ERR_get_error(), NULL));
return AVERROR(ENOMEM);
}
for (i = 0; i < n; i++) {
av_bprintf(&fingerprint, "%02X", md[i]);
if (i + 1 < n)
av_bprintf(&fingerprint, ":");
}
av_bprint_init(&buf, n*3, n*3);
if (!fingerprint.str || !strlen(fingerprint.str)) {
av_log(NULL, AV_LOG_ERROR, "TLS: Fingerprint is empty\n");
goto end;
}
for (int i = 0; i < n - 1; i++)
av_bprintf(&buf, "%02X:", md[i]);
av_bprintf(&buf, "%02X", md[n - 1]);
result = av_strdup(fingerprint.str);
if (!result) {
av_log(NULL, AV_LOG_ERROR, "TLS: Out of memory generating fingerprint\n");
}
end:
av_bprint_finalize(&fingerprint, NULL);
return result;
return av_bprint_finalize(&buf, fingerprint);
}
int ff_ssl_read_key_cert(char *key_url, char *cert_url, char *key_buf, size_t key_sz, char *cert_buf, size_t cert_sz, char **fingerprint)
@ -165,7 +120,6 @@ int ff_ssl_read_key_cert(char *key_url, char *cert_url, char *key_buf, size_t ke
AVBPrint key_bp, cert_bp;
EVP_PKEY *pkey = NULL;
X509 *cert = NULL;
char *key_tem = NULL, *cert_tem = NULL;
/* To prevent a crash during cleanup, always initialize it. */
av_bprint_init(&key_bp, 1, MAX_CERTIFICATE_SIZE);
@ -211,29 +165,18 @@ int ff_ssl_read_key_cert(char *key_url, char *cert_url, char *key_buf, size_t ke
goto end;
}
key_tem = pkey_to_pem_string(pkey);
cert_tem = cert_to_pem_string(cert);
pkey_to_pem_string(pkey, key_buf, key_sz);
cert_to_pem_string(cert, cert_buf, cert_sz);
snprintf(key_buf, key_sz, "%s", key_tem);
snprintf(cert_buf, cert_sz, "%s", cert_tem);
/* Generate fingerprint. */
if (fingerprint) {
*fingerprint = generate_fingerprint(cert);
if (!*fingerprint) {
av_log(NULL, AV_LOG_ERROR, "TLS: Failed to generate fingerprint from %s\n", cert_url);
ret = AVERROR(EIO);
goto end;
}
}
ret = x509_fingerprint(cert, fingerprint);
if (ret < 0)
av_log(NULL, AV_LOG_ERROR, "TLS: Failed to generate fingerprint from %s\n", cert_url);
end:
BIO_free(key_b);
av_bprint_finalize(&key_bp, NULL);
BIO_free(cert_b);
av_bprint_finalize(&cert_bp, NULL);
av_free(key_tem);
av_free(cert_tem);
EVP_PKEY_free(pkey);
X509_free(cert);
return ret;
@ -376,12 +319,9 @@ static int openssl_gen_certificate(EVP_PKEY *pkey, X509 **cert, char **fingerpri
goto einval_end;
}
if (fingerprint) {
*fingerprint = generate_fingerprint(*cert);
if (!*fingerprint) {
goto enomem_end;
}
}
ret = x509_fingerprint(*cert, fingerprint);
if (ret < 0)
goto end;
goto end;
enomem_end:
@ -403,7 +343,6 @@ int ff_ssl_gen_key_cert(char *key_buf, size_t key_sz, char *cert_buf, size_t cer
int ret = 0;
EVP_PKEY *pkey = NULL;
X509 *cert = NULL;
char *key_tem = NULL, *cert_tem = NULL;
ret = openssl_gen_private_key(&pkey);
if (ret < 0) goto error;
@ -411,14 +350,9 @@ int ff_ssl_gen_key_cert(char *key_buf, size_t key_sz, char *cert_buf, size_t cer
ret = openssl_gen_certificate(pkey, &cert, fingerprint);
if (ret < 0) goto error;
key_tem = pkey_to_pem_string(pkey);
cert_tem = cert_to_pem_string(cert);
pkey_to_pem_string(pkey, key_buf, key_sz);
cert_to_pem_string(cert, cert_buf, cert_sz);
snprintf(key_buf, key_sz, "%s", key_tem);
snprintf(cert_buf, cert_sz, "%s", cert_tem);
av_free(key_tem);
av_free(cert_tem);
error:
X509_free(cert);
EVP_PKEY_free(pkey);
@ -427,7 +361,7 @@ error:
/**
* Deserialize a PEMencoded private or public key from a NUL-terminated C string.
* Deserialize a PEM-encoded private or public key from a NUL-terminated C string.
*
* @param pem_str The PEM text, e.g.
* "-----BEGIN PRIVATE KEY-----\n\n-----END PRIVATE KEY-----\n"
@ -458,7 +392,7 @@ static EVP_PKEY *pkey_from_pem_string(const char *pem_str, int is_priv)
}
/**
* Deserialize a PEMencoded certificate from a NUL-terminated C string.
* Deserialize a PEM-encoded certificate from a NUL-terminated C string.
*
* @param pem_str The PEM text, e.g.
* "-----BEGIN CERTIFICATE-----\n\n-----END CERTIFICATE-----\n"
@ -542,12 +476,6 @@ int ff_dtls_export_materials(URLContext *h, char *dtls_srtp_materials, size_t ma
return 0;
}
int ff_dtls_state(URLContext *h)
{
TLSContext *c = h->priv_data;
return c->tls_shared.state;
}
static int print_ssl_error(URLContext *h, int ret)
{
TLSContext *c = h->priv_data;
@ -722,7 +650,6 @@ static int dtls_handshake(URLContext *h)
goto end;
ret = 0;
c->tls_shared.state = DTLS_STATE_FINISHED;
end:
return ret;
}

View file

@ -681,12 +681,6 @@ int ff_dtls_export_materials(URLContext *h, char *dtls_srtp_materials, size_t ma
#endif
}
int ff_dtls_state(URLContext *h)
{
TLSContext *c = h->priv_data;
return c->tls_shared.state;
}
static void init_sec_buffer(SecBuffer *buffer, unsigned long type,
void *data, unsigned long size)
{
@ -1111,7 +1105,6 @@ static int tls_handshake(URLContext *h)
#endif
c->connected = 1;
s->state = DTLS_STATE_FINISHED;
fail:
return ret;

View file

@ -198,9 +198,6 @@ typedef struct WHIPContext {
/* The state of the RTC connection. */
enum WHIPState state;
/* The callback return value for DTLS. */
int dtls_ret;
int dtls_closed;
/* Parameters for the input audio and video codecs. */
AVCodecParameters *audio_par;
@ -348,41 +345,6 @@ static av_cold int certificate_key_init(AVFormatContext *s)
return ret;
}
/**
* When DTLS state change.
*/
static int dtls_context_on_state(AVFormatContext *s, const char* type, const char* desc)
{
int ret = 0;
WHIPContext *whip = s->priv_data;
int state = ff_dtls_state(whip->dtls_uc);
if (state == DTLS_STATE_CLOSED) {
whip->dtls_closed = 1;
av_log(whip, AV_LOG_VERBOSE, "DTLS session closed, type=%s, desc=%s, elapsed=%dms\n",
type ? type : "", desc ? desc : "", ELAPSED(whip->whip_starttime, av_gettime()));
goto error;
}
if (state == DTLS_STATE_FAILED) {
whip->state = WHIP_STATE_FAILED;
av_log(whip, AV_LOG_ERROR, "DTLS session failed, type=%s, desc=%s\n",
type ? type : "", desc ? desc : "");
whip->dtls_ret = AVERROR(EIO);
goto error;
}
if (state == DTLS_STATE_FINISHED && whip->state < WHIP_STATE_DTLS_FINISHED) {
whip->state = WHIP_STATE_DTLS_FINISHED;
whip->whip_dtls_time = av_gettime();
av_log(whip, AV_LOG_VERBOSE, "DTLS handshake is done, elapsed=%dms\n",
ELAPSED(whip->whip_starttime, av_gettime()));
return ret;
}
error:
return -1;
}
static av_cold int dtls_initialize(AVFormatContext *s)
{
WHIPContext *whip = s->priv_data;
@ -1326,9 +1288,18 @@ next_packet:
/* If got any DTLS messages, handle it. */
if (is_dtls_packet(whip->buf, ret) && whip->state >= WHIP_STATE_ICE_CONNECTED || whip->state == WHIP_STATE_DTLS_CONNECTING) {
whip->state = WHIP_STATE_DTLS_CONNECTING;
if ((ret = ffurl_handshake(whip->dtls_uc)) < 0)
ret = ffurl_handshake(whip->dtls_uc);
if (ret < 0) {
whip->state = WHIP_STATE_FAILED;
av_log(whip, AV_LOG_VERBOSE, "DTLS session failed\n");
goto end;
dtls_context_on_state(s, NULL, NULL);
}
if (!ret) {
whip->state = WHIP_STATE_DTLS_FINISHED;
whip->whip_dtls_time = av_gettime();
av_log(whip, AV_LOG_VERBOSE, "DTLS handshake is done, elapsed=%dms\n",
ELAPSED(whip->whip_starttime, whip->whip_dtls_time));
}
goto next_packet;
}
}
@ -1771,10 +1742,8 @@ static av_cold int whip_init(AVFormatContext *s)
goto end;
end:
if (ret < 0 && whip->state < WHIP_STATE_FAILED)
if (ret < 0)
whip->state = WHIP_STATE_FAILED;
if (ret >= 0 && whip->state >= WHIP_STATE_FAILED && whip->dtls_ret < 0)
ret = whip->dtls_ret;
return ret;
}
@ -1822,12 +1791,8 @@ static int whip_write_packet(AVFormatContext *s, AVPacket *pkt)
}
end:
if (ret < 0 && whip->state < WHIP_STATE_FAILED)
if (ret < 0)
whip->state = WHIP_STATE_FAILED;
if (ret >= 0 && whip->state >= WHIP_STATE_FAILED && whip->dtls_ret < 0)
ret = whip->dtls_ret;
if (ret >= 0 && whip->dtls_closed)
ret = AVERROR(EIO);
return ret;
}

View file

@ -229,6 +229,8 @@ static inline int ff_thread_setname(const char *name)
#endif
#elif HAVE_PTHREAD_SET_NAME_NP
pthread_set_name_np(pthread_self(), name);
#elif HAVE_W32THREADS
ret = win32_thread_setname(name);
#else
ret = AVERROR(ENOSYS);
#endif