Compare commits

...

5 Commits

Author SHA1 Message Date
Frank Plowman 76827a6f3b lavc/hevc: Fix usage of slice segment in invalid state
Previously, we set s->slice_initialized to 0 to prevent other slice
segments from depending on this slice segment only if hls_slice_header
failed.  If decode_slice fails for some other reason, however, before
decode_slice_data is called to bring the context back into a consistent
state, then slices could depend on this slice segment while it is in an
invalid state.  This can cause segmentation faults and other sorts of
nastiness.  Patch fixes this by always setting s->slice_initialized to 0
while the state is inconsistent.

Resolves #11652.
2025-11-24 05:08:58 +00:00
Neal Gompa 069d465895 configure: Lower libdvdnav and libdvdread minimum versions for EL9
Red Hat Enterprise Linux 9 is one patch version lower than what
FFmpeg currently requests. The slightly older versions still result
in a working build of FFmpeg with DVD support, so allow those
versions to be consumed to build FFmpeg.

Signed-off-by: Neal Gompa <neal@gompa.dev>
2025-11-24 03:08:20 +00:00
James Almer 6f4a3be9dc avformat/movenc: add support for writing srat box
Signed-off-by: James Almer <jamrial@gmail.com>
2025-11-24 02:59:02 +00:00
Kacper Michajłow 148cf61585 fate: add missing options in config template
Fixes: f01c771577
Fixes: 523d688c2b
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
2025-11-24 02:47:08 +00:00
Kacper Michajłow 6cb002610b fate: add skip_clean option
This is useful if one wants to inspect build artifacts after running
fate.sh script.

Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
2025-11-24 02:47:08 +00:00
8 changed files with 69 additions and 24 deletions

4
configure vendored
View File

@ -7121,8 +7121,8 @@ enabled libdav1d && require_pkg_config libdav1d "dav1d >= 1.0.0" "dav1d
enabled libdavs2 && require_pkg_config libdavs2 "davs2 >= 1.6.0" davs2.h davs2_decoder_open
enabled libdc1394 && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new
enabled libdrm && check_pkg_config libdrm libdrm xf86drm.h drmGetVersion
enabled libdvdnav && require_pkg_config libdvdnav "dvdnav >= 6.1.1" dvdnav/dvdnav.h dvdnav_open2
enabled libdvdread && require_pkg_config libdvdread "dvdread >= 6.1.2" dvdread/dvd_reader.h DVDOpen2
enabled libdvdnav && require_pkg_config libdvdnav "dvdnav >= 6.1.0" dvdnav/dvdnav.h dvdnav_open2
enabled libdvdread && require_pkg_config libdvdread "dvdread >= 6.1.1" dvdread/dvd_reader.h DVDOpen2
enabled libfdk_aac && { check_pkg_config libfdk_aac fdk-aac "fdk-aac/aacenc_lib.h" aacEncOpen ||
{ require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac &&
warn "using libfdk without pkg-config"; } }

View File

@ -6,21 +6,27 @@ workdir= # directory in which to do all the work
#fate_recv="ssh -T fate@fate.ffmpeg.org" # command to submit report
comment= # optional description
build_only= # set to "yes" for a compile-only instance that skips tests
skip_clean= # set to "yes" to preserve build/install directories
ignore_tests=
# the following are optional and map to configure options
arch=
cpu=
toolchain=
cross_prefix=
as=
cc=
cxx=
ld=
nm=
target_os=
sysroot=
target_exec=
target_path=
target_samples=
extra_cflags=
extra_cxxflags=
extra_objcflags=
extra_ldflags=
extra_libs=
extra_conf= # extra configure options not covered above

View File

@ -3411,7 +3411,6 @@ fail:
ff_hevc_unref_frame(l->cur_frame, ~0);
l->cur_frame = NULL;
s->cur_frame = s->collocated_ref = NULL;
s->slice_initialized = 0;
return ret;
}
@ -3544,9 +3543,11 @@ static int decode_slice(HEVCContext *s, unsigned nal_idx, GetBitContext *gb)
return 0;
ret = hls_slice_header(&s->sh, s, gb);
if (ret < 0) {
// hls_slice_header() does not cleanup on failure thus the state now is inconsistent so we cannot use it on dependent slices
// Once hls_slice_header has been called, the context is inconsistent with the slice header
// until the context is reinitialized according to the contents of the new slice header
// at the start of decode_slice_data.
s->slice_initialized = 0;
if (ret < 0) {
return ret;
}

View File

@ -161,6 +161,18 @@ static int64_t update_size(AVIOContext *pb, int64_t pos)
return curpos - pos;
}
static int64_t update_size_and_version(AVIOContext *pb, int64_t pos, int version)
{
int64_t curpos = avio_tell(pb);
avio_seek(pb, pos, SEEK_SET);
avio_wb32(pb, curpos - pos); /* rewrite size */
avio_skip(pb, 4);
avio_w8(pb, version); /* rewrite version */
avio_seek(pb, curpos, SEEK_SET);
return curpos - pos;
}
static int co64_required(const MOVTrack *track)
{
if (track->entry > 0 && track->cluster[track->entry - 1].pos + track->data_offset > UINT32_MAX)
@ -1344,6 +1356,18 @@ static int mov_write_pcmc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
return update_size(pb, pos);
}
static int mov_write_srat_tag(AVIOContext *pb, MOVTrack *track)
{
int64_t pos = avio_tell(pb);
avio_wb32(pb, 0); /* size */
ffio_wfourcc(pb, "srat");
avio_wb32(pb, 0); /* version & flags */
avio_wb32(pb, track->par->sample_rate);
return update_size(pb, pos);
}
static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
{
int64_t pos = avio_tell(pb);
@ -1363,6 +1387,10 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
track->par->codec_id == AV_CODEC_ID_QDM2) {
version = 1;
}
} else if (track->mode == MODE_MP4) {
if (track->par->sample_rate > UINT16_MAX &&
(tag == MOV_MP4_IPCM_TAG || tag == MOV_MP4_FPCM_TAG))
version = 1;
}
avio_wb32(pb, 0); /* size */
@ -1395,6 +1423,8 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
avio_wb32(pb, track->sample_size);
avio_wb32(pb, get_samples_per_packet(track));
} else {
unsigned sample_rate = track->par->sample_rate;
if (track->mode == MODE_MOV) {
avio_wb16(pb, track->par->ch_layout.nb_channels);
if (track->par->codec_id == AV_CODEC_ID_PCM_U8 ||
@ -1415,6 +1445,9 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
avio_wb16(pb, 16);
}
avio_wb16(pb, 0);
while (sample_rate > UINT16_MAX)
sample_rate >>= 1;
}
avio_wb16(pb, 0); /* packet size (= 0) */
@ -1425,14 +1458,13 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
avio_wb32(pb, track->par->sample_rate);
else
avio_wb16(pb, track->par->sample_rate <= UINT16_MAX ?
track->par->sample_rate : 0);
avio_wb16(pb, sample_rate);
if (track->par->codec_id != AV_CODEC_ID_TRUEHD)
avio_wb16(pb, 0); /* Reserved */
}
if (version == 1) { /* SoundDescription V1 extended info */
if (track->mode == MODE_MOV && version == 1) { /* SoundDescription V1 extended info */
if (mov_pcm_le_gt16(track->par->codec_id) ||
mov_pcm_be_gt16(track->par->codec_id))
avio_wb32(pb, 1); /* must be 1 for uncompressed formats */
@ -1478,6 +1510,8 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
ret = mov_write_dmlp_tag(s, pb, track);
else if (tag == MOV_MP4_IPCM_TAG || tag == MOV_MP4_FPCM_TAG) {
if (track->par->sample_rate > UINT16_MAX)
mov_write_srat_tag(pb, track);
if (track->par->ch_layout.nb_channels > 1)
ret = mov_write_chnl_tag(s, pb, track);
if (ret < 0)
@ -1508,6 +1542,9 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
((ret = mov_write_btrt_tag(pb, track)) < 0))
return ret;
if (track->mode == MODE_MP4)
track->entry_version = version;
ret = update_size(pb, pos);
return ret;
}
@ -3122,7 +3159,7 @@ static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext
track->last_stsd_index = stsd_index_back;
return update_size(pb, pos);
return update_size_and_version(pb, pos, track->entry_version);
}
static int mov_write_ctts_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)

View File

@ -86,6 +86,7 @@ typedef struct MOVFragmentInfo {
typedef struct MOVTrack {
int mode;
int entry_version;
int entry, entry_written;
unsigned timescale;
uint64_t time;

View File

@ -95,7 +95,7 @@ fate()(
)
clean(){
rm -rf ${build} ${inst}
test "$skip_clean" = "yes" || rm -rf ${build} ${inst}
}
report(){

View File

@ -251,8 +251,8 @@ fate-mov-channel-description: CMD = transcode wav $(TARGET_PATH)/tests/data/asyn
# Test PCM in mp4 and channel layout
FATE_MOV_FFMPEG-$(call TRANSCODE, PCM_S16LE, MP4 MOV, WAV_DEMUXER PAN_FILTER) \
+= fate-mov-mp4-pcm
fate-mov-mp4-pcm: tests/data/asynth-44100-1.wav tests/data/filtergraphs/mov-mp4-pcm
fate-mov-mp4-pcm: CMD = transcode wav $(TARGET_PATH)/tests/data/asynth-44100-1.wav mp4 "-/filter_complex $(TARGET_PATH)/tests/data/filtergraphs/mov-mp4-pcm -map [mono] -map [stereo] -map [2.1] -map [5.1] -map [7.1] -c:a pcm_s16le" "-map 0 -c copy -frames:a 0"
fate-mov-mp4-pcm: tests/data/asynth-96000-1.wav tests/data/filtergraphs/mov-mp4-pcm
fate-mov-mp4-pcm: CMD = transcode wav $(TARGET_PATH)/tests/data/asynth-96000-1.wav mp4 "-/filter_complex $(TARGET_PATH)/tests/data/filtergraphs/mov-mp4-pcm -map [mono] -map [stereo] -map [2.1] -map [5.1] -map [7.1] -c:a pcm_s16le" "-map 0 -c copy -frames:a 0"
# Test floating sample format PCM in mp4 and unusual channel layout
FATE_MOV_FFMPEG-$(call TRANSCODE, PCM_F32LE, MP4 MOV, WAV_DEMUXER PAN_FILTER) \

View File

@ -1,27 +1,27 @@
0c6802135e9eb442201c0c1b001259d6 *tests/data/fate/mov-mp4-pcm.mp4
10587977 tests/data/fate/mov-mp4-pcm.mp4
#tb 0: 1/44100
531c4a3389a66d305fb247691f4b14ab *tests/data/fate/mov-mp4-pcm.mp4
23044177 tests/data/fate/mov-mp4-pcm.mp4
#tb 0: 1/96000
#media_type 0: audio
#codec_id 0: pcm_s16le
#sample_rate 0: 44100
#sample_rate 0: 96000
#channel_layout_name 0: mono
#tb 1: 1/44100
#tb 1: 1/96000
#media_type 1: audio
#codec_id 1: pcm_s16le
#sample_rate 1: 44100
#sample_rate 1: 96000
#channel_layout_name 1: stereo
#tb 2: 1/44100
#tb 2: 1/96000
#media_type 2: audio
#codec_id 2: pcm_s16le
#sample_rate 2: 44100
#sample_rate 2: 96000
#channel_layout_name 2: 2.1
#tb 3: 1/44100
#tb 3: 1/96000
#media_type 3: audio
#codec_id 3: pcm_s16le
#sample_rate 3: 44100
#sample_rate 3: 96000
#channel_layout_name 3: 5.1
#tb 4: 1/44100
#tb 4: 1/96000
#media_type 4: audio
#codec_id 4: pcm_s16le
#sample_rate 4: 44100
#sample_rate 4: 96000
#channel_layout_name 4: 7.1