Re: [FFmpeg-devel] aarch64: Implement support for elf_aux_info(3) on FreeBSD and OpenBSD
Le 28 juillet 2024 07:37:51 GMT+03:00, Brad Smith a écrit : >On 2024-07-26 7:56 a.m., Rémi Denis-Courmont wrote: >> >> Le 26 juillet 2024 13:58:34 GMT+03:00, Brad Smith >> a écrit : >>> aarch64: Implement support for elf_aux_info(3) on FreeBSD and OpenBSD >>> >>> FreeBSD 12.0+, OpenBSD -current and what will be OpenBSD 7.6 support >>> elf_aux_info(3). >>> >>> Signed-off-by: Brad Smith >>> --- >>> configure | 2 ++ >>> libavutil/aarch64/cpu.c | 23 ++- >>> 2 files changed, 24 insertions(+), 1 deletion(-) >>> >>> diff --git a/configure b/configure >>> index f6f5c29fea..e80b549582 100755 >>> --- a/configure >>> +++ b/configure >>> @@ -2366,6 +2366,7 @@ SYSTEM_FUNCS=" >>> clock_gettime >>> closesocket >>> CommandLineToArgvW >>> +elf_aux_info >>> fcntl >>> getaddrinfo >>> getauxval >>> @@ -6565,6 +6566,7 @@ check_func_headers mach/mach_time.h mach_absolute_time >>> check_func_headers stdlib.h getenv >>> check_func_headers sys/stat.h lstat >>> check_func_headers sys/auxv.h getauxval >>> +check_func_headers sys/auxv.h elf_aux_info >>> check_func_headers sys/sysctl.h sysctlbyname >>> >>> check_func_headers windows.h GetModuleHandle >>> diff --git a/libavutil/aarch64/cpu.c b/libavutil/aarch64/cpu.c >>> index cfa9306663..05272b4db4 100644 >>> --- a/libavutil/aarch64/cpu.c >>> +++ b/libavutil/aarch64/cpu.c >>> @@ -42,6 +42,27 @@ static int detect_flags(void) >>> return flags; >>> } >>> >>> +#elif (defined(__FreeBSD__) || defined(__OpenBSD__)) && HAVE_ELF_AUX_INFO >>> +#include >>> +#include >>> + >>> +static int detect_flags(void) >>> +{ >>> +int flags = 0; >>> + >>> +unsigned long hwcap = 0; >>> +elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap); >>> +unsigned long hwcap2 = 0; >>> +elf_aux_info(AT_HWCAP2, &hwcap2, sizeof hwcap2); >>> + >>> +if (hwcap & HWCAP_ASIMDDP) >>> +flags |= AV_CPU_FLAG_DOTPROD; >>> +if (hwcap2 & HWCAP2_I8MM) >>> +flags |= AV_CPU_FLAG_I8MM; >>> + >>> +return flags; >>> +} >>> + >> Can't getauxval() be implemented with elf_aux_info(), or vice versa? It >> seems that otherwise the code should be identical to that from Linux. > >QEMU has qemu_getauxval() for example as a wrapper. I will be using this >elsewhere for arm, ppc and riscv. > >I could split this up, but I am not sure where to place such a function. I don't personally have a strong opinion on the details, I just don't fancy unnecessary duplication. > >>> #elif defined(__APPLE__) && HAVE_SYSCTLBYNAME >>> #include >>> >>> @@ -65,7 +86,7 @@ static int detect_flags(void) >>> return flags; >>> } >>> >>> -#elif defined(__OpenBSD__) >>> +#elif defined(__OpenBSD__) && !HAVE_ELF_AUX_INFO >>> #include >>> #include >>> #include >> ___ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> >> To unsubscribe, visit link above, or email >> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". >___ >ffmpeg-devel mailing list >ffmpeg-devel@ffmpeg.org >https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > >To unsubscribe, visit link above, or email >ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 0/7] avformat/dvdvideodec: Bug fixes, seeking support, and menu chapters
This patch set starts with a critical bug fix to resolve packet drops, then follows on with seeking support and menu chapter marker support. In addition, some cleanup occurs and documentation/logging is improved. Seeking can be tested with mpv, ``` /mpv "av://dvdvideo:$IN" ``` Compare/view on GitHub: https://github.com/FFmpeg/FFmpeg/compare/master...Marth64x:FFmpeg:20240728_dvdvideofix?expand=1 Net addition is 69 lines across the demuxer and docs. Signed-off-by: Marth64 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/7] avformat/dvdvideodec: Fix racy PTS calculation and frame drops
DVDs naturally consist of segmented MPEG-PS blobs within a VOB (i.e. VOBs are not linear). NAV packs set the segment boundaries. When switching between segments, discontinuities occur and thus the subdemuxer needs to be reset. The current approach to manage this is by invoking ff_read_frame_flush() on the subdemuxer context, via a callback function which is invoked during the menu or dvdnav block functions. The same subdemuxer context is used throughout the demux, with a stretched PTS wrap bits value (64) + disabled overflow correction, and then flushed on each segment. Eventually, a play_end context variable is set to declare EOF. However, this approach is wrong and racy. The block read flushes the demuxer before the frame read is complete, causing frames to drop on discontinuity. The play_end signal likewise ends playback before the frame read is complete, causing frames to drop at end of the title. To compound the issue, the PTS wrap bits value of 64 is wrong; the VOBU limit is actually 32 and the overflow correction should work. Instead, EOF the MPEG-PS subdemuxer organically when each VOB segment ends, and re-open it if needed with the offset after the full frame read is complete. In doing so, correct the PTS wrap behavior to 32 bits, remove the racy play_end/segment_started signals and the callback pattern. The behavior is now more similar to the HLS/DASH demuxers. This commit fixes five intertwined issues, yielding an accurate demux: (1) Racy segment switching (2) Racy EOF signaling (3) Off-by-one leading to missed packets at start of menus (4) Incorrect PTS wrap behavior (5) Unnecessary frame discard workarounds removed Signed-off-by: Marth64 --- libavformat/dvdvideodec.c | 198 +++--- 1 file changed, 100 insertions(+), 98 deletions(-) diff --git a/libavformat/dvdvideodec.c b/libavformat/dvdvideodec.c index 7a859071c3..e745165e00 100644 --- a/libavformat/dvdvideodec.c +++ b/libavformat/dvdvideodec.c @@ -58,7 +58,7 @@ #define DVDVIDEO_MAX_PS_SEARCH_BLOCKS 128 #define DVDVIDEO_BLOCK_SIZE 2048 #define DVDVIDEO_TIME_BASE_Q(AVRational) { 1, 9 } -#define DVDVIDEO_PTS_WRAP_BITS 64 /* VOBUs use 32 (PES allows 33) */ +#define DVDVIDEO_PTS_WRAP_BITS 32 /* VOBUs use 32 (PES allows 33) */ #define DVDVIDEO_LIBDVDX_LOG_BUFFER_SIZE1024 #define PCI_START_BYTE 45 /* complement dvdread's DSI_START_BYTE */ @@ -116,8 +116,9 @@ typedef struct DVDVideoPlaybackState { int pgc_nb_pg_est; /* number of PGs as reported by IFOs */ int pgcn; /* ID of the PGC we are playing */ int pgn;/* ID of the PG we are in now */ +int ptm_discont;/* signal that a PTM discontinuity occurred */ +int64_t ptm_offset; /* PTM discontinuity offset (as NAV value) */ int ptt;/* ID of the chapter we are in now */ -int64_t ts_offset; /* PTS discontinuity offset (ex. VOB change) */ uint32_tvobu_duration; /* duration of the current VOBU */ uint32_tvobu_e_ptm; /* end PTM of the current VOBU */ int vtsn; /* ID of the active VTS (video title set) */ @@ -164,10 +165,11 @@ typedef struct DVDVideoDemuxContext { /* playback control */ int64_t first_pts; /* the PTS of the first video keyframe */ -int play_end; /* signal EOF to the parent demuxer */ -DVDVideoPlaybackState play_state; /* the active playback state */ int play_started; /* signal that playback has started */ -int segment_started;/* signal that subdemuxer is on a segment */ +DVDVideoPlaybackState play_state; /* the active playback state */ +int64_t pts_offset; /* PTS discontinuity offset (ex. VOB change) */ +int seek_warned;/* signal that we warned about seeking limits */ +int subdemux_reset; /* signal that subdemuxer should be reset */ } DVDVideoDemuxContext; static void dvdvideo_libdvdread_log(void *opaque, dvd_logger_level_t level, @@ -344,7 +346,7 @@ static int dvdvideo_menu_open(AVFormatContext *s, DVDVideoPlaybackState *state) } /* make sure the PGC is valid */ -state->pgcn = c->opt_pgc - 1; +state->pgcn = c->opt_pgc; state->pgc = pgci_ut->lu[c->opt_menu_lu - 1].pgcit->pgci_srp[c->opt_pgc - 1].pgc; if (!state->pgc || !state->pgc->program_map || !s
[FFmpeg-devel] [PATCH 2/7] avformat/dvdvideodec: Implement seeking
Player applications can now enjoy seeking while playing back a title. Accuracy is at the mercy of what libdvdnav offers, which is currently dvdnav_jump_to_sector_by_time(). Signed-off-by: Marth64 --- libavformat/dvdvideodec.c | 93 ++- 1 file changed, 82 insertions(+), 11 deletions(-) diff --git a/libavformat/dvdvideodec.c b/libavformat/dvdvideodec.c index e745165e00..e8301b1173 100644 --- a/libavformat/dvdvideodec.c +++ b/libavformat/dvdvideodec.c @@ -110,6 +110,7 @@ typedef struct DVDVideoPlaybackState { int in_pgc; /* if our navigator is in the PGC */ int in_ps; /* if our navigator is in the program stream */ int in_vts; /* if our navigator is in the VTS */ +int is_seeking; /* relax navigation path while seeking */ int64_t nav_pts;/* PTS according to IFO, not frame-accurate */ uint64_tpgc_duration_est; /* estimated duration as reported by IFO */ uint64_tpgc_elapsed;/* the elapsed time of the PGC, cell-relative */ @@ -722,7 +723,8 @@ static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState state->in_pgc = 1; } -} else if (state->celln >= e_cell->cellN || state->pgn > cur_pgn) { +} else if (!state->is_seeking && + (state->celln >= e_cell->cellN || state->pgn > cur_pgn)) { return AVERROR_EOF; } @@ -735,7 +737,7 @@ static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState if (!state->in_pgc) continue; -if ((state->ptt > 0 && state->ptt > cur_ptt) || +if ((!state->is_seeking && state->ptt > 0 && state->ptt > cur_ptt) || (c->opt_chapter_end > 0 && cur_ptt > c->opt_chapter_end)) { return AVERROR_EOF; } @@ -807,13 +809,15 @@ static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState return AVERROR_INPUT_CHANGED; } -memcpy(buf, &nav_buf, nav_len); - if (state->pgn != cur_pgn) av_log(s, AV_LOG_WARNING, "Unexpected PG change (expected=%d actual=%d); " "this could be due to a missed NAV packet\n", state->pgn, cur_pgn); +memcpy(buf, &nav_buf, nav_len); + +state->is_seeking = 0; + return nav_len; case DVDNAV_WAIT: if (dvdnav_wait_skip(state->dvdnav) != DVDNAV_STATUS_OK) { @@ -1659,17 +1663,17 @@ static int dvdvideo_read_packet(AVFormatContext *s, AVPacket *pkt) } av_log(s, AV_LOG_TRACE, "st=%d pts=%" PRId64 " dts=%" PRId64 " " -"pts_offset=%" PRId64 " first_pts=%" PRId64 "\n", +"pts_offset=%" PRId64 " first_pts=%" PRId64 " is_seeking=%d\n", pkt->stream_index, pkt->pts, pkt->dts, -c->pts_offset); +c->pts_offset, c->first_pts, c->play_state.is_seeking); return 0; discard: av_log(s, AV_LOG_VERBOSE, "Discarding packet @ st=%d pts=%" PRId64 " dts=%" PRId64 " " - "st_matched=%d\n", + "st_matched=%d is_seeking=%d\n", st_matched ? pkt->stream_index : -1, pkt->pts, pkt->dts, - st_matched); + st_matched, c->play_state.is_seeking); return FFERROR_REDO; } @@ -1690,6 +1694,72 @@ static int dvdvideo_close(AVFormatContext *s) return 0; } +static int dvdvideo_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) +{ +DVDVideoDemuxContext *c = s->priv_data; +int ret; +int64_t new_nav_pts; +pci_t* new_nav_pci; +dsi_t* new_nav_dsi; + +if (c->opt_menu || c->opt_chapter_start > 1) { +av_log(s, AV_LOG_ERROR, "Seeking is not compatible with menus or chapter extraction\n"); + +return AVERROR_PATCHWELCOME; +} + +if ((flags & AVSEEK_FLAG_BYTE)) +return AVERROR(ENOSYS); + +if (timestamp < 0) +return AVERROR(EINVAL); + +if (!c->seek_warned) { +av_log(s, AV_LOG_WARNING, "Seeking is inherently unreliable and will result " + "in imprecise timecodes from this point\n"); +c->seek_warned = 1; +} + +/* XXX(PATCHWELCOME): use dvdnav_jump_to_sector_by_time(c->play_state.dvdnav, timestamp, 0) + * when it is available in a released version of libdvdnav;
[FFmpeg-devel] [PATCH 3/7] avformat/dvdvideodec: Combine libdvdread and libdvdnav log callbacks
The methods are effectively the same but reference different public enums, so roll them up into a macro. Signed-off-by: Marth64 --- libavformat/dvdvideodec.c | 64 +++ 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/libavformat/dvdvideodec.c b/libavformat/dvdvideodec.c index e8301b1173..f6373d8ade 100644 --- a/libavformat/dvdvideodec.c +++ b/libavformat/dvdvideodec.c @@ -173,40 +173,28 @@ typedef struct DVDVideoDemuxContext { int subdemux_reset; /* signal that subdemuxer should be reset */ } DVDVideoDemuxContext; -static void dvdvideo_libdvdread_log(void *opaque, dvd_logger_level_t level, -const char *msg, va_list msg_va) -{ -AVFormatContext *s = opaque; -char msg_buf[DVDVIDEO_LIBDVDX_LOG_BUFFER_SIZE]; -int lavu_level = AV_LOG_DEBUG; - -vsnprintf(msg_buf, sizeof(msg_buf), msg, msg_va); - -if (level == DVD_LOGGER_LEVEL_ERROR) -lavu_level = AV_LOG_ERROR; -else if (level == DVD_LOGGER_LEVEL_WARN) -lavu_level = AV_LOG_WARNING; - -av_log(s, lavu_level, "libdvdread: %s\n", msg_buf); -} - -static void dvdvideo_libdvdnav_log(void *opaque, dvdnav_logger_level_t level, - const char *msg, va_list msg_va) -{ -AVFormatContext *s = opaque; -char msg_buf[DVDVIDEO_LIBDVDX_LOG_BUFFER_SIZE]; -int lavu_level = AV_LOG_DEBUG; - -vsnprintf(msg_buf, sizeof(msg_buf), msg, msg_va); - -if (level == DVDNAV_LOGGER_LEVEL_ERROR) -lavu_level = AV_LOG_ERROR; -/* some discs have invalid language codes set for menus, which throws noisy warnings */ -else if (level == DVDNAV_LOGGER_LEVEL_WARN && !av_strstart(msg, "Language", NULL)) -lavu_level = AV_LOG_WARNING; - -av_log(s, lavu_level, "libdvdnav: %s\n", msg_buf); -} +#define LIBDVDX_LOG_CALLBACK(X, CB_TYPE, LEVEL_TYPE, LEVEL_PREFIX) \ +static void dvdvideo_##X##_log(void *o, LEVEL_TYPE level, const char *msg, va_list msg_va) \ +{ \ +AVFormatContext *s = o; \ +char msg_buf[DVDVIDEO_LIBDVDX_LOG_BUFFER_SIZE]; \ +int lavu_level = AV_LOG_DEBUG; \ +\ +vsnprintf(msg_buf, sizeof(msg_buf), msg, msg_va); \ +\ +if (level == LEVEL_PREFIX##_ERROR) \ +lavu_level = AV_LOG_ERROR; \ +else if (level == LEVEL_PREFIX##_WARN && \ + !av_strstart(msg, "Language", NULL)) /* muffle menus with invalid language */ \ +lavu_level = AV_LOG_WARNING; \ +\ +av_log(s, lavu_level, #X": %s\n", msg_buf); \ +} \ +\ +static const CB_TYPE dvdvideo_##X##_log_cb = (CB_TYPE) { .pf_log = dvdvideo_##X##_log }; \ + +LIBDVDX_LOG_CALLBACK(libdvdread, dvd_logger_cb,dvd_logger_level_t, DVD_LOGGER_LEVEL) +LIBDVDX_LOG_CALLBACK(libdvdnav, dvdnav_logger_cb, dvdnav_logger_level_t, DVDNAV_LOGGER_LEVEL) static void dvdvideo_ifo_close(AVFormatContext *s) { @@ -226,11 +214,9 @@ static int dvdvideo_ifo_open(AVFormatContext *s) { DVDVideoDemuxContext *c = s->priv_data; -dvd_logger_cb dvdread_log_cb; title_info_t title_info; -dvdread_log_cb = (dvd_logger_cb) { .pf_log = dvdvideo_libdvdread_log }; -c->dvdread = DVDOpen2(s, &dvdread_log_cb, s->url); +c->dvdread = DVDOpen2(s, &dvdvideo_libdvdread_log_cb, s->url); if (!c->dvdread) { av_log(s, AV_LOG_ERROR, "Unable to open the DVD-Video structure\n"); @@ -516,15 +502,13 @@ static int dvdvideo_play_open(AVFormatContext *s, DVDVideoPlaybackState *state) { DVDVideoDemuxContext *c = s->priv_data; -dvdnav_logger_cb dvdnav_log_cb; dvdnav_status_t dvdnav_open_status; int32_t disc_region_mask; int32_t player_region_mask; int cur_title, cur_pgcn, cur_pgn; pgc_t *pgc; -dvdnav_log_cb = (dvdnav_logger_cb) { .pf_log = dvdvideo_libdvdnav_log }; -dvdnav_open_status = dvdnav_open2(&state->dvdnav, s, &dvdnav_log_cb, s->url); +dvdnav_open_status = dvdnav_open2(&state->dvdnav, s, &dvdvideo_libdvdnav_log_cb, s->url); if (!state->dvdnav || dvdnav_open_status != DVDNAV_STATUS_OK || -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 4/7] avformat/dvdvideodec: Chapter markers and trimming for menus
Menus can have chapter markers by way of cells, and empty menus can be detected with existing functionality. Menu selection also is in need of usability improvement. Implement chapter markers for menus, let the trim function detect empty menus, remove the unnecessary ceremony around the -pg option by simply defaulting it to 1, and finally default the menu_vts option to 1 since most DVD menus can be found there. Signed-off-by: Marth64 --- libavformat/dvdvideodec.c | 106 +- 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/libavformat/dvdvideodec.c b/libavformat/dvdvideodec.c index f6373d8ade..a908acfa7f 100644 --- a/libavformat/dvdvideodec.c +++ b/libavformat/dvdvideodec.c @@ -367,6 +367,14 @@ static int dvdvideo_menu_open(AVFormatContext *s, DVDVideoPlaybackState *state) if (c->opt_menu_vts > 0) state->in_vts= 1; +if (c->opt_trim && !dvdvideo_is_pgc_promising(s, state->pgc)) { +av_log(s, AV_LOG_ERROR, "Menu LU %d, VTS %d, PGC %d looks empty; " +"if you want to try anyway, disable the trim option\n", +c->opt_menu_lu, c->opt_menu_vts, c->opt_pgc); + +return AVERROR_INVALIDDATA; +} + if (!(state->vob_file = DVDOpenFile(c->dvdread, c->opt_menu_vts, DVD_READ_MENU_VOBS))) { av_log(s, AV_LOG_ERROR, !c->opt_menu_vts ? "Unable to open main menu VOB (VIDEO_TS.VOB)\n" : @@ -527,7 +535,7 @@ static int dvdvideo_play_open(AVFormatContext *s, DVDVideoPlaybackState *state) goto end_dvdnav_error; } -if (c->opt_pgc > 0 && c->opt_pg > 0) { +if (c->opt_pgc > 0) { if (dvdnav_program_play(state->dvdnav, c->opt_title, c->opt_pgc, c->opt_pg) != DVDNAV_STATUS_OK) { av_log(s, AV_LOG_ERROR, "Unable to start playback at title %d, PGC %d, PG %d\n", c->opt_title, c->opt_pgc, c->opt_pg); @@ -893,8 +901,8 @@ static int dvdvideo_chapters_setup_preindex(AVFormatContext *s) { DVDVideoDemuxContext *c = s->priv_data; -int ret = 0, interrupt = 0; -int nb_chapters = 0, last_ptt = c->opt_chapter_start; +int ret, partn, last_partn; +int interrupt = 0, nb_chapters = 0; uint64_t cur_chapter_offset = 0, cur_chapter_duration = 0; DVDVideoPlaybackState state = {0}; @@ -902,27 +910,38 @@ static int dvdvideo_chapters_setup_preindex(AVFormatContext *s) int is_nav_packet; if (c->opt_chapter_start == c->opt_chapter_end) -return ret; +return 0; -if ((ret = dvdvideo_play_open(s, &state)) < 0) -return ret; +if (c->opt_menu) { +if ((ret = dvdvideo_menu_open(s, &state)) < 0) +return ret; +last_partn = state.celln; +} else { +if ((ret = dvdvideo_play_open(s, &state)) < 0) +return ret; +last_partn = c->opt_chapter_start; +} if (state.pgc->nr_of_programs == 1) goto end_close; -av_log(s, AV_LOG_INFO, - "Indexing chapter markers, this will take a long time. Please wait...\n"); +av_log(s, AV_LOG_INFO, "Indexing chapter markers, this may take a long time. Please wait...\n"); while (!(interrupt = ff_check_interrupt(&s->interrupt_callback))) { -ret = dvdvideo_play_next_ps_block(s, &state, nav_buf, DVDVIDEO_BLOCK_SIZE, - &is_nav_packet); +if (c->opt_menu) +ret = dvdvideo_menu_next_ps_block(s, &state, nav_buf, DVDVIDEO_BLOCK_SIZE, &is_nav_packet); +else +ret = dvdvideo_play_next_ps_block(s, &state, nav_buf, DVDVIDEO_BLOCK_SIZE, &is_nav_packet); + if (ret < 0 && ret != AVERROR_EOF) goto end_close; if (!is_nav_packet && ret != AVERROR_EOF) continue; -if (state.ptt == last_ptt) { +partn = c->opt_menu ? state.celln : state.ptt; + +if (partn == last_partn) { cur_chapter_duration += state.vobu_duration; /* ensure we add the last chapter */ if (ret != AVERROR_EOF) @@ -941,7 +960,7 @@ static int dvdvideo_chapters_setup_preindex(AVFormatContext *s) cur_chapter_offset += cur_chapter_duration; cur_chapter_duration = state.vobu_duration; -last_ptt = state.ptt; +last_partn = partn; if (ret == AVERROR_EOF) break; @@ -961,7 +980,10 @@ static int dvdvideo_chapters_setup_preindex(AVFormatContext *s) ret = 0; end_close: -dvdvideo_play_close(s, &state); +if (c->opt_menu) +dvdvideo_menu_close(s, &state); +else +dvdvideo_play_close(s, &state); return ret; } @@ -1512,47 +1534,47 @@ static int dvdvideo_read_header(AVFormatContext *s) int ret; if (c->opt_menu) { -if (c->opt_region || -c->opt_title > 1|| -c->opt_preindex || -
[FFmpeg-devel] [PATCH 5/7] avformat/dvdvideodec: Remove unused headers
Signed-off-by: Marth64 --- libavformat/dvdvideodec.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavformat/dvdvideodec.c b/libavformat/dvdvideodec.c index a908acfa7f..afc7836038 100644 --- a/libavformat/dvdvideodec.c +++ b/libavformat/dvdvideodec.c @@ -44,8 +44,6 @@ #include "libavutil/mem.h" #include "libavutil/opt.h" #include "libavutil/samplefmt.h" -#include "libavutil/time.h" -#include "libavutil/timestamp.h" #include "avformat.h" #include "avio_internal.h" -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 6/7] avformat/dvdvideodec: Simplify/clarify logs, comments, and class name
Signed-off-by: Marth64 --- libavformat/dvdvideodec.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libavformat/dvdvideodec.c b/libavformat/dvdvideodec.c index afc7836038..04c5cbea8e 100644 --- a/libavformat/dvdvideodec.c +++ b/libavformat/dvdvideodec.c @@ -21,7 +21,7 @@ /* * See doc/demuxers.texi for a high-level overview. * - * The tactical approach is as follows: + * The tactical approach for title playback is as follows: * 1) Open the volume with dvdread * 2) Analyze the user-requested title and PGC coordinates in the IFO structures * 3) Request playback at the coordinates and chosen angle with dvdnav @@ -565,8 +565,8 @@ static int dvdvideo_play_open(AVFormatContext *s, DVDVideoPlaybackState *state) } if (c->opt_trim && !dvdvideo_is_pgc_promising(s, pgc)) { -av_log(s, AV_LOG_ERROR, "Title %d, PGC %d looks empty (may consist of padding cells), " -"if you want to try anyway, disable the -trim option\n", +av_log(s, AV_LOG_ERROR, "Title %d, PGC %d looks empty (may consist of padding cells); " +"if you want to try anyway, disable the trim option\n", c->opt_title, state->pgcn); return AVERROR_INVALIDDATA; @@ -757,7 +757,7 @@ static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState if (!state->in_ps) { if (c->opt_trim && !dvdvideo_is_cell_promising(s, state->pgc, state->celln)) { -av_log(s, AV_LOG_INFO, "Skipping padding cell #%d\n", state->celln); +av_log(s, AV_LOG_INFO, "Trimming padding cell #%d\n", state->celln); i = 0; continue; @@ -1175,8 +1175,7 @@ static int dvdvideo_audio_stream_analyze(AVFormatContext *s, audio_attr_t audio_ if (audio_attr.application_mode == 1) { entry->disposition |= AV_DISPOSITION_KARAOKE; -av_log(s, AV_LOG_WARNING, "Extended karaoke metadata is not supported at this time " - "(stream id=%d)\n", startcode); +av_log(s, AV_LOG_WARNING, "Karaoke extensions not supported (stream id=%d)\n", startcode); } if (audio_attr.code_extension == 2) @@ -1770,7 +1769,7 @@ static const AVOption dvdvideo_options[] = { }; static const AVClass dvdvideo_class = { -.class_name = "DVD-Video demuxer", +.class_name = "dvdvideo", .item_name = av_default_item_name, .option = dvdvideo_options, .version= LIBAVUTIL_VERSION_INT -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 7/7] doc/demuxers: update dvdvideodec documentation
Signed-off-by: Marth64 --- doc/demuxers.texi | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/demuxers.texi b/doc/demuxers.texi index 04293c4813..d67be0312e 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -384,7 +384,7 @@ Default is 0, the first language unit. @item menu_vts @var{int} The VTS where the menu lives, or 0 if it is a VMG menu (root-level). -Default is 0, VMG menu. +Default is 1, the menu in the first VTS. @item pgc @var{int} The entry PGC to start playback, in conjunction with @option{pg}. @@ -396,17 +396,16 @@ Default is 0, automatically resolve from value of @option{title}. @item pg @var{int} The entry PG to start playback, in conjunction with @option{pgc}. Alternative to setting @option{title}. -Chapter markers are not supported at this time. -Default is 0, automatically resolve from value of @option{title}, or -start from the beginning (PG 1) of the menu. +This option is ignored without @option{pgc}. +Default is the first PG segment of the PGC (PG 1). @item preindex @var{bool} Enable this to have accurate chapter (PTT) markers and duration measurement, which requires a slow second pass read in order to index the chapter marker -timestamps from NAV packets. This is non-ideal extra work for real optical drives. +timestamps from NAV packets. This also enables chapter markers on menus. +The drawback is that this adds busy work for real optical drives. It is recommended and faster to use this option with a backup of the DVD structure stored on a hard drive. Not compatible with @option{pgc} and @option{pg}. -Not applicable to menus. Default is 0, false. @item trim @var{bool} -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 1/1] lavfi/vf_gopromax_opencl: add GoPor Max 360 video filter
On Sun, Jul 28, 2024 at 01:42:09AM +0900, TADANO Tokumei wrote: > > On 2024/07/27 13:30, TADANO Tokumei wrote: > > Add an OpenCL filter for filtering GoPro Max native .360 files > > into standard equirectangular or youtube equiangular cubemap (eac) > > projection. > > > > The .360 file contains separated two video streams. > > This filter combine two streams into single stream with standard > > format. > > --- > > doc/filters.texi | 78 +++ > > libavfilter/Makefile | 2 + > > libavfilter/allfilters.c | 1 + > > libavfilter/opencl/gopromax.cl | 280 > > libavfilter/opencl_source.h | 1 + > > libavfilter/vf_gopromax_opencl.c | 351 +++ > > 6 files changed, 713 insertions(+) > > create mode 100644 libavfilter/opencl/gopromax.cl > > create mode 100644 libavfilter/vf_gopromax_opencl.c > > The patchwork failed, but it was caused by opencl.c (not by this patch): > > In file included from ./libavutil/common.h:48:0, > from ./libavutil/avutil.h:301, > from ./libavutil/opt.h:31, > from libavdevice/sdl2.c:31: > ./config.h:335:0: warning: 'HAVE_PTHREAD_SETNAME_NP' redefined > #define HAVE_PTHREAD_SETNAME_NP 0 > In file included from /usr/include/SDL2/SDL_stdinc.h:31:0, > from /usr/include/SDL2/SDL_main.h:25, > from /usr/include/SDL2/SDL.h:32, > from libavdevice/sdl2.c:26: > /usr/include/SDL2/SDL_config.h:186:0: note: this is the location of the > previous definition > #define HAVE_PTHREAD_SETNAME_NP 1 > In file included from libavfilter/opencl.h:31:0, > from libavfilter/opencl.c:26: > ./libavutil/hwcontext_opencl.h:25:10: fatal error: CL/cl.h: No such file or > directory > #include > ^ > compilation terminated. > make: *** [libavfilter/opencl.o] Error 1 with this patch it fails here on ubuntu: /usr/bin/ld: libavfilter/libavfilter.a(opencl.o): undefined reference to symbol 'clBuildProgram@@OPENCL_1.0' /usr/bin/ld: /usr/local/cuda/targets/x86_64-linux/lib/libOpenCL.so.1: error adding symbols: DSO missing from command line thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB If you fake or manipulate statistics in a paper in physics you will never get a job again. If you fake or manipulate statistics in a paper in medicin you will get a job for life at the pharma industry. signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 03/22] avcodec/dovi_rpuenc: also copy ext blocks to dovi ctx
From: Niklas Haas As the comment implies, DOVIContext.ext_blocks should also reflect the current state after ff_dovi_rpu_generate(). Fluff for now, but will be needed once we start implementing metadata compression for extension blocks as well. --- libavcodec/dovi_rpuenc.c | 12 1 file changed, 12 insertions(+) diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c index a14c9cc181..f0cfecc91b 100644 --- a/libavcodec/dovi_rpuenc.c +++ b/libavcodec/dovi_rpuenc.c @@ -506,6 +506,12 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, } } +if (metadata->num_ext_blocks && !s->ext_blocks) { +s->ext_blocks = ff_refstruct_allocz(sizeof(AVDOVIDmData) * AV_DOVI_MAX_EXT_BLOCKS); +if (!s->ext_blocks) +return AVERROR(ENOMEM); +} + vdr_dm_metadata_present = memcmp(color, &ff_dovi_color_default, sizeof(*color)); use_prev_vdr_rpu = !memcmp(s->vdr[vdr_rpu_id], mapping, sizeof(*mapping)); if (num_ext_blocks_v1 || num_ext_blocks_v2) @@ -636,6 +642,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, } if (vdr_dm_metadata_present) { +size_t ext_sz; const int denom = profile == 4 ? (1 << 30) : (1 << 28); set_ue_golomb(pb, color->dm_metadata_id); /* affected_dm_id */ set_ue_golomb(pb, color->dm_metadata_id); /* current_dm_id */ @@ -673,6 +680,11 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, for (int i = 0; i < metadata->num_ext_blocks; i++) generate_ext_v2(pb, av_dovi_get_ext(metadata, i)); } + +ext_sz = FFMIN(sizeof(AVDOVIDmData), metadata->ext_block_size); +for (int i = 0; i < metadata->num_ext_blocks; i++) +memcpy(&s->ext_blocks[i], av_dovi_get_ext(metadata, i), ext_sz); +s->num_ext_blocks = metadata->num_ext_blocks; } else { s->color = &ff_dovi_color_default; s->num_ext_blocks = 0; -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 02/22] avcodec/dovi_rpudec: implement validation for compression
From: Niklas Haas Add some error checking. I've limited it to AV_EF_CAREFUL and AV_EF_COMPLIANT for now, because we can technically decode such RPUs just fine. --- libavcodec/dovi_rpudec.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c index 375e6e560b..bf6e5075d1 100644 --- a/libavcodec/dovi_rpudec.c +++ b/libavcodec/dovi_rpudec.c @@ -314,6 +314,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, uint8_t use_prev_vdr_rpu; uint8_t use_nlq; uint8_t profile; +uint8_t compression = s->cfg.dv_profile ? s->cfg.dv_md_compression : 0; if (rpu_size < 5) return AVERROR_INVALIDDATA; @@ -459,6 +460,20 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, return AVERROR_INVALIDDATA; } +if (err_recognition & (AV_EF_COMPLIANT | AV_EF_CAREFUL)) { +if (profile < 8 && compression) { +av_log(s->logctx, AV_LOG_ERROR, "Profile %d RPUs should not use " + "metadata compression.", profile); +return AVERROR_INVALIDDATA; +} + +if (use_prev_vdr_rpu && !compression) { +av_log(s->logctx, AV_LOG_ERROR, "Uncompressed RPUs should not have " + "use_prev_vdr_rpu=1\n"); +return AVERROR_INVALIDDATA; +} +} + if (use_prev_vdr_rpu) { int prev_vdr_rpu_id = get_ue_golomb_31(gb); VALIDATE(prev_vdr_rpu_id, 0, DOVI_MAX_DM_ID); -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 04/22] avcodec/dovi_rpuenc: eliminate unnecessary loop
From: Niklas Haas This struct itself contains vdr_rpu_id, so we can never match it except in the case of i == vdr_rpu_id. So just directly use this ID. --- libavcodec/dovi_rpuenc.c | 11 +-- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c index f0cfecc91b..63cbde8718 100644 --- a/libavcodec/dovi_rpuenc.c +++ b/libavcodec/dovi_rpuenc.c @@ -463,16 +463,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, return AVERROR_INVALIDDATA; } -vdr_rpu_id = -1; -for (int i = 0; i <= DOVI_MAX_DM_ID; i++) { -if (s->vdr[i] && !memcmp(s->vdr[i], mapping, sizeof(*mapping))) { -vdr_rpu_id = i; -break; -} else if (vdr_rpu_id < 0 && (!s->vdr[i] || i == DOVI_MAX_DM_ID)) { -vdr_rpu_id = i; -} -} - +vdr_rpu_id = mapping->vdr_rpu_id; if (!s->vdr[vdr_rpu_id]) { s->vdr[vdr_rpu_id] = ff_refstruct_allocz(sizeof(AVDOVIDataMapping)); if (!s->vdr[vdr_rpu_id]) -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 01/22] avutil/dovi_meta: document static vs dynamic ext blocks
From: Niklas Haas --- libavutil/dovi_meta.h | 28 +++- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/libavutil/dovi_meta.h b/libavutil/dovi_meta.h index c942d0e133..5e8a1e43d7 100644 --- a/libavutil/dovi_meta.h +++ b/libavutil/dovi_meta.h @@ -301,26 +301,28 @@ typedef struct AVDOVIDmLevel255 { } AVDOVIDmLevel255; /** - * Dolby Vision metadata extension block. + * Dolby Vision metadata extension block. Dynamic extension blocks may change + * from frame to frame, while static blocks are constant throughout the entire + * sequence. * * @note sizeof(AVDOVIDmData) is not part of the public API. */ typedef struct AVDOVIDmData { uint8_t level; /* [1, 255] */ union { -AVDOVIDmLevel1 l1; -AVDOVIDmLevel2 l2; /* may appear multiple times */ -AVDOVIDmLevel3 l3; -AVDOVIDmLevel4 l4; -AVDOVIDmLevel5 l5; -AVDOVIDmLevel6 l6; +AVDOVIDmLevel1 l1; /* dynamic */ +AVDOVIDmLevel2 l2; /* dynamic, may appear multiple times */ +AVDOVIDmLevel3 l3; /* dynamic */ +AVDOVIDmLevel4 l4; /* dynamic */ +AVDOVIDmLevel5 l5; /* dynamic */ +AVDOVIDmLevel6 l6; /* static */ /* level 7 is currently unused */ -AVDOVIDmLevel8 l8; /* may appear multiple times */ -AVDOVIDmLevel9 l9; -AVDOVIDmLevel10 l10; /* may appear multiple times */ -AVDOVIDmLevel11 l11; -AVDOVIDmLevel254 l254; -AVDOVIDmLevel255 l255; +AVDOVIDmLevel8 l8; /* dynamic, may appear multiple times */ +AVDOVIDmLevel9 l9; /* dynamic */ +AVDOVIDmLevel10 l10; /* static, may appear multiple times */ +AVDOVIDmLevel11 l11; /* dynamic */ +AVDOVIDmLevel254 l254; /* static */ +AVDOVIDmLevel255 l255; /* static */ }; } AVDOVIDmData; -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 05/22] avcodec/dovi_rpuenc: respect dv_md_compression
From: Niklas Haas Limited mode can only ever maintain a single VDR RPU reference, and furthermore requires vdr_rpu_id == 0. So in practice, it will only ever use VDR RPU slot 0. All remaining slots get flushed in this case, to avoid leaking partial state. --- libavcodec/dovi_rpuenc.c | 26 +- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c index 63cbde8718..2a6131eff5 100644 --- a/libavcodec/dovi_rpuenc.c +++ b/libavcodec/dovi_rpuenc.c @@ -464,12 +464,37 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, } vdr_rpu_id = mapping->vdr_rpu_id; +use_prev_vdr_rpu = 0; + if (!s->vdr[vdr_rpu_id]) { s->vdr[vdr_rpu_id] = ff_refstruct_allocz(sizeof(AVDOVIDataMapping)); if (!s->vdr[vdr_rpu_id]) return AVERROR(ENOMEM); } +switch (s->cfg.dv_md_compression) { +case AV_DOVI_COMPRESSION_LIMITED: +/* Limited metadata compression requires vdr_rpi_id == 0 */ +if (vdr_rpu_id != 0) +break; +/* fall through */ +case AV_DOVI_COMPRESSION_EXTENDED: +if (s->vdr[vdr_rpu_id]) +use_prev_vdr_rpu = !memcmp(s->vdr[vdr_rpu_id], mapping, sizeof(*mapping)); +break; +case AV_DOVI_COMPRESSION_RESERVED: +return AVERROR(EINVAL); +} + +if (s->cfg.dv_md_compression != AV_DOVI_COMPRESSION_EXTENDED) { +/* Flush VDRs to avoid leaking old state; maintaining multiple VDR + * references requires extended compression */ +for (int i = 0; i <= DOVI_MAX_DM_ID; i++) { +if (i != vdr_rpu_id) +ff_refstruct_unref(&s->vdr[i]); +} +} + num_ext_blocks_v1 = num_ext_blocks_v2 = 0; for (int i = 0; i < metadata->num_ext_blocks; i++) { const AVDOVIDmData *dm = av_dovi_get_ext(metadata, i); @@ -504,7 +529,6 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, } vdr_dm_metadata_present = memcmp(color, &ff_dovi_color_default, sizeof(*color)); -use_prev_vdr_rpu = !memcmp(s->vdr[vdr_rpu_id], mapping, sizeof(*mapping)); if (num_ext_blocks_v1 || num_ext_blocks_v2) vdr_dm_metadata_present = 1; -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 12/22] avcodec/bsf/dovi_rpu: add new bitstream filter
From: Niklas Haas This can be used to strip dovi metadata, or enable/disable dovi metadata compression. Possibly more use cases in the future. --- configure | 1 + doc/bitstream_filters.texi | 23 +++ libavcodec/bitstream_filters.c | 1 + libavcodec/bsf/Makefile| 1 + libavcodec/bsf/dovi_rpu.c | 279 + 5 files changed, 305 insertions(+) create mode 100644 libavcodec/bsf/dovi_rpu.c diff --git a/configure b/configure index f6f5c29fea..6107fb8745 100755 --- a/configure +++ b/configure @@ -3443,6 +3443,7 @@ aac_adtstoasc_bsf_select="adts_header mpeg4audio" av1_frame_merge_bsf_select="cbs_av1" av1_frame_split_bsf_select="cbs_av1" av1_metadata_bsf_select="cbs_av1" +dovi_rpu_bsf_select="cbs_h265 cbs_av1 dovi_rpudec dovi_rpuenc" dts2pts_bsf_select="cbs_h264 h264parse" eac3_core_bsf_select="ac3_parser" evc_frame_merge_bsf_select="evcparse" diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi index c03f04f858..e1cb87a522 100644 --- a/doc/bitstream_filters.texi +++ b/doc/bitstream_filters.texi @@ -101,6 +101,29 @@ Remove zero padding at the end of a packet. Extract the core from a DCA/DTS stream, dropping extensions such as DTS-HD. +@section dovi_rpu + +Manipulate Dolby Vision metadata in a HEVC/AV1 bitstream, optionally enabling +metadata compression. + +@table @option +@item strip +If enabled, strip all Dolby Vision metadata (configuration record + RPU data +blocks) from the stream. +@item compression +Which compression level to enable. +@table @samp +@item none +No metadata compression. +@item limited +Limited metadata compression scheme. Should be compatible with most devices. +This is the default. +@item extended +Extended metadata compression. Devices are not required to support this. Note +that this level currently behaves the same as @samp{limited} in libavcodec. +@end table +@end table + @section dump_extra Add extradata to the beginning of the filtered packets except when diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c index 138246c50e..f923411bee 100644 --- a/libavcodec/bitstream_filters.c +++ b/libavcodec/bitstream_filters.c @@ -31,6 +31,7 @@ extern const FFBitStreamFilter ff_av1_metadata_bsf; extern const FFBitStreamFilter ff_chomp_bsf; extern const FFBitStreamFilter ff_dump_extradata_bsf; extern const FFBitStreamFilter ff_dca_core_bsf; +extern const FFBitStreamFilter ff_dovi_rpu_bsf; extern const FFBitStreamFilter ff_dts2pts_bsf; extern const FFBitStreamFilter ff_dv_error_marker_bsf; extern const FFBitStreamFilter ff_eac3_core_bsf; diff --git a/libavcodec/bsf/Makefile b/libavcodec/bsf/Makefile index fb70ad0c21..40b7fc6e9b 100644 --- a/libavcodec/bsf/Makefile +++ b/libavcodec/bsf/Makefile @@ -19,6 +19,7 @@ OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF) += bsf/h264_mp4toannexb.o OBJS-$(CONFIG_H264_REDUNDANT_PPS_BSF) += bsf/h264_redundant_pps.o OBJS-$(CONFIG_HAPQA_EXTRACT_BSF) += bsf/hapqa_extract.o OBJS-$(CONFIG_HEVC_METADATA_BSF) += bsf/h265_metadata.o +OBJS-$(CONFIG_DOVI_RPU_BSF) += bsf/dovi_rpu.o OBJS-$(CONFIG_HEVC_MP4TOANNEXB_BSF) += bsf/hevc_mp4toannexb.o OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF)+= bsf/imx_dump_header.o OBJS-$(CONFIG_MEDIA100_TO_MJPEGB_BSF) += bsf/media100_to_mjpegb.o diff --git a/libavcodec/bsf/dovi_rpu.c b/libavcodec/bsf/dovi_rpu.c new file mode 100644 index 00..29e6e57bd9 --- /dev/null +++ b/libavcodec/bsf/dovi_rpu.c @@ -0,0 +1,279 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/common.h" +#include "libavutil/mem.h" +#include "libavutil/opt.h" + +#include "bsf.h" +#include "bsf_internal.h" +#include "cbs.h" +#include "cbs_bsf.h" +#include "cbs_av1.h" +#include "cbs_h265.h" +#include "dovi_rpu.h" +#include "h2645data.h" +#include "h265_profile_level.h" +#include "itut35.h" + +#include "hevc/hevc.h" + +typedef struct DoviRpuContext { +CBSBSFContext common; +DOVIContext dec; +DOVIContext enc; + +int strip; +int compression; +} DoviRpuContext; + +static int update_rpu(AVBSFContext *bsf, const AVPacket *pkt, int flags, + const uint8_t *rpu, size_t rpu_size, + uint8_t **out_rpu, int
[FFmpeg-devel] [PATCH 14/22] avcodec/dovi_rpu: separate static ext blocks
From: Niklas Haas Static and dynamic extension blocks are handled differently by metadata compression, so we need to separate the extension block array into two. --- libavcodec/dovi_rpu.h| 20 ++-- libavcodec/dovi_rpudec.c | 31 +-- libavcodec/dovi_rpuenc.c | 11 --- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h index ed5bfa7b26..f3ccc27ae8 100644 --- a/libavcodec/dovi_rpu.h +++ b/libavcodec/dovi_rpu.h @@ -33,8 +33,10 @@ #define DOVI_MAX_DM_ID 15 typedef struct DOVIExt { -AVDOVIDmData dm[AV_DOVI_MAX_EXT_BLOCKS]; -int num_dm; +AVDOVIDmData dm_static[7]; ///< static extension blocks +AVDOVIDmData dm_dynamic[25]; ///< dynamic extension blocks +int num_static; +int num_dynamic; } DOVIExt; typedef struct DOVIContext { @@ -191,4 +193,18 @@ int ff_dovi_guess_profile_hevc(const AVDOVIRpuDataHeader *hdr); /* Default values for AVDOVIColorMetadata */ extern const AVDOVIColorMetadata ff_dovi_color_default; +static inline int ff_dovi_rpu_extension_is_static(int level) +{ +switch (level) { +case 6: +case 10: +case 32: /* reserved as static by spec */ +case 254: +case 255: +return 1; +default: +return 0; +} +} + #endif /* AVCODEC_DOVI_RPU_H */ diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c index 1650547c80..6ef7a88ffd 100644 --- a/libavcodec/dovi_rpudec.c +++ b/libavcodec/dovi_rpudec.c @@ -51,9 +51,10 @@ int ff_dovi_get_metadata(DOVIContext *s, AVDOVIMetadata **out_metadata) if (s->ext_blocks) { const DOVIExt *ext = s->ext_blocks; size_t ext_sz = FFMIN(sizeof(AVDOVIDmData), dovi->ext_block_size); -for (int i = 0; i < ext->num_dm; i++) -memcpy(av_dovi_get_ext(dovi, i), &ext->dm[i], ext_sz); -dovi->num_ext_blocks = ext->num_dm; +for (int i = 0; i < ext->num_static; i++) +memcpy(av_dovi_get_ext(dovi, dovi->num_ext_blocks++), &ext->dm_static[i], ext_sz); +for (int i = 0; i < ext->num_dynamic; i++) +memcpy(av_dovi_get_ext(dovi, dovi->num_ext_blocks++), &ext->dm_dynamic[i], ext_sz); } *out_metadata = dovi; @@ -296,15 +297,23 @@ static int parse_ext_blocks(DOVIContext *s, GetBitContext *gb, int ver) while (num_ext_blocks--) { AVDOVIDmData *dm; - -if (ext->num_dm >= FF_ARRAY_ELEMS(ext->dm)) -return AVERROR_INVALIDDATA; -dm = &ext->dm[ext->num_dm++]; +uint8_t level; ext_block_length = get_ue_golomb_31(gb); -dm->level = get_bits(gb, 8); +level = get_bits(gb, 8); start_pos = get_bits_count(gb); +if (ff_dovi_rpu_extension_is_static(level)) { +if (ext->num_static >= FF_ARRAY_ELEMS(ext->dm_static)) +return AVERROR_INVALIDDATA; +dm = &ext->dm_static[ext->num_static++]; +} else { +if (ext->num_dynamic >= FF_ARRAY_ELEMS(ext->dm_dynamic)) +return AVERROR_INVALIDDATA; +dm = &ext->dm_dynamic[ext->num_dynamic++]; +} + +dm->level = level; switch (ver) { case 1: ret = parse_ext_v1(s, gb, dm); break; case 2: ret = parse_ext_v2(s, gb, dm, ext_block_length); break; @@ -674,8 +683,10 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, color->source_diagonal = get_bits(gb, 10); /* Parse extension blocks */ -if (s->ext_blocks) -s->ext_blocks->num_dm = 0; +if (s->ext_blocks) { +DOVIExt *ext = s->ext_blocks; +ext->num_static = ext->num_dynamic = 0; +} if ((ret = parse_ext_blocks(s, gb, 1)) < 0) { ff_dovi_ctx_unref(s); return ret; diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c index 667d681c25..7193e2d9c8 100644 --- a/libavcodec/dovi_rpuenc.c +++ b/libavcodec/dovi_rpuenc.c @@ -758,9 +758,14 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, if (ext) { size_t ext_sz = FFMIN(sizeof(AVDOVIDmData), metadata->ext_block_size); -for (int i = 0; i < metadata->num_ext_blocks; i++) -memcpy(&ext->dm[i], av_dovi_get_ext(metadata, i), ext_sz); -ext->num_dm = metadata->num_ext_blocks; +ext->num_static = ext->num_dynamic = 0; +for (int i = 0; i < metadata->num_ext_blocks; i++) { +const AVDOVIDmData *dm = av_dovi_get_ext(metadata, i); +if (ff_dovi_rpu_extension_is_static(dm->level)) +memcpy(&ext->dm_static[ext->num_static++], dm, ext_sz); +else +memcpy(&ext->dm_dynamic[ext->num_dynamic++], dm, ext_sz); +} } } else { s->color = &ff_dovi_color_default; -- 2.45.2 ___ ffmpeg-devel
[FFmpeg-devel] [PATCH 16/22] avcodec/dovi_rpudec: implement limited DM decompression
From: Niklas Haas This implements the limited DM metadata compression scheme described in chapter 9 of the dolby vision bitstream specification. The spec is a bit unclear about how to handle the presence of static metadata inside compressed frames; in that it doesn't explicitly forbid an encoder from repeating redundant metadata. In theory, we would need to detect this case and then strip the corresponding duplicate metadata from the existing set of static metadata. However, this is difficult to implement - esspecially for the case of metadata blocks which may be internally repeated (e.g. level 10). That said, the spec states outright that static metadata should be constant throughout the entire sequence, so a sane bitstream should not have any static metadata values changing from one frame to the next (at least up to a keyframe boundary), and therefore they should never be present in compressed frames. As a consequence, it makes sense to treat this as an error state regardless. (Ignoring them by default, or erroring if either AV_EF_EXPLODE or AV_EF_AGGRESSIVE are set) I was not able to find such samples in the wild (outside of artificially produced test cases for this exact scenario), so I don't think we need to worry about it until somebody produces one. --- libavcodec/dovi_rpudec.c | 100 +-- 1 file changed, 65 insertions(+), 35 deletions(-) diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c index 3465665961..91c9e41926 100644 --- a/libavcodec/dovi_rpudec.c +++ b/libavcodec/dovi_rpudec.c @@ -281,7 +281,8 @@ static int parse_ext_v2(DOVIContext *s, GetBitContext *gb, AVDOVIDmData *dm, return 0; } -static int parse_ext_blocks(DOVIContext *s, GetBitContext *gb, int ver) +static int parse_ext_blocks(DOVIContext *s, GetBitContext *gb, int ver, +int compression, int err_recognition) { int num_ext_blocks, ext_block_length, start_pos, parsed_bits, ret; DOVIExt *ext = s->ext_blocks; @@ -296,6 +297,7 @@ static int parse_ext_blocks(DOVIContext *s, GetBitContext *gb, int ver) } while (num_ext_blocks--) { +AVDOVIDmData dummy; AVDOVIDmData *dm; uint8_t level; @@ -304,9 +306,17 @@ static int parse_ext_blocks(DOVIContext *s, GetBitContext *gb, int ver) start_pos = get_bits_count(gb); if (ff_dovi_rpu_extension_is_static(level)) { -if (ext->num_static >= FF_ARRAY_ELEMS(ext->dm_static)) -return AVERROR_INVALIDDATA; -dm = &ext->dm_static[ext->num_static++]; +if (compression) { +av_log(s->logctx, AV_LOG_WARNING, "Compressed DM RPU contains " + "static extension block level %d\n", level); +if (err_recognition & (AV_EF_AGGRESSIVE | AV_EF_EXPLODE)) +return AVERROR_INVALIDDATA; +dm = &dummy; +} else { +if (ext->num_static >= FF_ARRAY_ELEMS(ext->dm_static)) +return AVERROR_INVALIDDATA; +dm = &ext->dm_static[ext->num_static++]; +} } else { if (ext->num_dynamic >= FF_ARRAY_ELEMS(ext->dm_dynamic)) return AVERROR_INVALIDDATA; @@ -342,6 +352,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, uint8_t rpu_type; uint8_t vdr_seq_info_present; uint8_t vdr_dm_metadata_present; +uint8_t dm_compression = 0; uint8_t use_prev_vdr_rpu; uint8_t use_nlq; uint8_t profile; @@ -454,7 +465,6 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, int bl_bit_depth_minus8 = get_ue_golomb_31(gb); int el_bit_depth_minus8 = get_ue_golomb_long(gb); int vdr_bit_depth_minus8 = get_ue_golomb_31(gb); -int reserved_zero_3bits; /* ext_mapping_idc is in the upper 8 bits of el_bit_depth_minus8 */ int ext_mapping_idc = el_bit_depth_minus8 >> 8; el_bit_depth_minus8 = el_bit_depth_minus8 & 0xFF; @@ -468,8 +478,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, hdr->ext_mapping_idc_5_7 = ext_mapping_idc >> 5; hdr->vdr_bit_depth = vdr_bit_depth_minus8 + 8; hdr->spatial_resampling_filter_flag = get_bits1(gb); -reserved_zero_3bits = get_bits(gb, 3); -VALIDATE(reserved_zero_3bits, 0, 0); +dm_compression = get_bits(gb, 3); hdr->el_spatial_resampling_filter_flag = get_bits1(gb); hdr->disable_residual_flag = get_bits1(gb); } @@ -481,6 +490,17 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, } vdr_dm_metadata_present = get_bits1(gb); +if (dm_compression > 1) { +/* It seems no device supports this */ +av_log(s->logctx, AV_LOG_ERROR, "Dynamic metadata compression is not " + "ye
[FFmpeg-devel] [PATCH 17/22] avcodec/dovi_rpudec: sanitize DM data before decoding
From: Niklas Haas Some DM types do not fill the whole struct, so just clear it entirely before going filling the decoded values. --- libavcodec/dovi_rpudec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c index 91c9e41926..9f295d4fe4 100644 --- a/libavcodec/dovi_rpudec.c +++ b/libavcodec/dovi_rpudec.c @@ -323,6 +323,7 @@ static int parse_ext_blocks(DOVIContext *s, GetBitContext *gb, int ver, dm = &ext->dm_dynamic[ext->num_dynamic++]; } +memset(dm, 0, sizeof(*dm)); dm->level = level; switch (ver) { case 1: ret = parse_ext_v1(s, gb, dm); break; -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 15/22] avcodec/dovi_rpudec: don't unnecessarily allocate DOVIExt
From: Niklas Haas --- libavcodec/dovi_rpudec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c index 6ef7a88ffd..3465665961 100644 --- a/libavcodec/dovi_rpudec.c +++ b/libavcodec/dovi_rpudec.c @@ -289,7 +289,7 @@ static int parse_ext_blocks(DOVIContext *s, GetBitContext *gb, int ver) num_ext_blocks = get_ue_golomb_31(gb); align_get_bits(gb); -if (!ext) { +if (num_ext_blocks && !ext) { ext = s->ext_blocks = ff_refstruct_allocz(sizeof(*s->ext_blocks)); if (!ext) return AVERROR(ENOMEM); -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 20/22] avcodec/dovi_rpudec: error out on strange RPU formats
From: Niklas Haas Better safe than sorry. --- libavcodec/dovi_rpudec.c | 4 1 file changed, 4 insertions(+) diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c index 9f295d4fe4..878950d66d 100644 --- a/libavcodec/dovi_rpudec.c +++ b/libavcodec/dovi_rpudec.c @@ -482,6 +482,10 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, dm_compression = get_bits(gb, 3); hdr->el_spatial_resampling_filter_flag = get_bits1(gb); hdr->disable_residual_flag = get_bits1(gb); +} else { +avpriv_request_sample(s->logctx, "Unsupported RPU format 0x%x\n", hdr->rpu_format); +ff_dovi_ctx_unref(s); +return AVERROR_PATCHWELCOME; } } else { /* lack of documentation/samples */ -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 19/22] avcodec/dovi_rpuenc: slightly improve profile autodetection
From: Niklas Haas In the absence of an RPU header, we can consult the colorspace tags to make a more informed guess about whether we're looking at profile 5 or profile 8. --- libavcodec/dovi_rpuenc.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c index c73805037c..8113ec44bf 100644 --- a/libavcodec/dovi_rpuenc.c +++ b/libavcodec/dovi_rpuenc.c @@ -79,7 +79,20 @@ int ff_dovi_configure_ext(DOVIContext *s, AVCodecParameters *codecpar, switch (codecpar->codec_id) { case AV_CODEC_ID_AV1: dv_profile = 10; break; case AV_CODEC_ID_H264: dv_profile = 9; break; -case AV_CODEC_ID_HEVC: dv_profile = hdr ? ff_dovi_guess_profile_hevc(hdr) : 8; break; +case AV_CODEC_ID_HEVC: +if (hdr) { +dv_profile = ff_dovi_guess_profile_hevc(hdr); +break; +} + +/* This is likely to be proprietary IPTPQc2 */ +if (codecpar->color_space == AVCOL_SPC_IPT_C2 || +(codecpar->color_space == AVCOL_SPC_UNSPECIFIED && + codecpar->color_trc == AVCOL_TRC_UNSPECIFIED)) +dv_profile = 5; +else +dv_profile = 8; +break; default: /* No other encoder should be calling this! */ av_assert0(0); -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 22/22] avcodec/libx265: raise strictness of missing DV error
From: Niklas Haas See previous commit for justification --- libavcodec/libx265.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c index 718bd21b20..325c4fdd07 100644 --- a/libavcodec/libx265.c +++ b/libavcodec/libx265.c @@ -792,9 +792,11 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, } } else if (ctx->dovi.cfg.dv_profile) { av_log(avctx, AV_LOG_ERROR, "Dolby Vision enabled, but received frame " - "without AV_FRAME_DATA_DOVI_METADATA"); -free_picture(ctx, &x265pic); -return AVERROR_INVALIDDATA; + "without AV_FRAME_DATA_DOVI_METADATA\n"); +if (avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT) { +free_picture(ctx, &x265pic); +return AVERROR_INVALIDDATA; +} } #endif } -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 18/22] avcodec/dovi_rpuenc: implement DM metadata compression
From: Niklas Haas This implements limited metadata compression. To be a bit more lenient, we try and re-order the static extension blocks when testing for an exact match. For sanity, and to avoid producing bitstreams we couldn't ourselves decode, we don't accept partial matches - if some extension blocks change while others remain static, compression is disabled for the entire frame. This shouldn't be an issue in practice because static extension blocks are stated to remain constant throughout the entire sequence. --- libavcodec/dovi_rpuenc.c | 166 +-- 1 file changed, 124 insertions(+), 42 deletions(-) diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c index 7193e2d9c8..c73805037c 100644 --- a/libavcodec/dovi_rpuenc.c +++ b/libavcodec/dovi_rpuenc.c @@ -257,6 +257,62 @@ fail: return ret; } +/* Compares only the static DM metadata parts of AVDOVIColorMetadata (excluding + * dm_metadata_id and scene_refresh_flag) */ +static int cmp_dm_level0(const AVDOVIColorMetadata *dm1, + const AVDOVIColorMetadata *dm2) +{ +int ret; +for (int i = 0; i < FF_ARRAY_ELEMS(dm1->ycc_to_rgb_matrix); i++) { +if ((ret = av_cmp_q(dm1->ycc_to_rgb_matrix[i], dm2->ycc_to_rgb_matrix[i]))) +return ret; +} + +for (int i = 0; i < FF_ARRAY_ELEMS(dm1->ycc_to_rgb_offset); i++) { +if ((ret = av_cmp_q(dm1->ycc_to_rgb_offset[i], dm2->ycc_to_rgb_offset[i]))) +return ret; +} + +for (int i = 0; i < FF_ARRAY_ELEMS(dm1->rgb_to_lms_matrix); i++) { +if ((ret = av_cmp_q(dm1->rgb_to_lms_matrix[i], dm2->rgb_to_lms_matrix[i]))) +return ret; +} + +return memcmp(&dm1->signal_eotf, &dm2->signal_eotf, + sizeof(AVDOVIColorMetadata) -offsetof(AVDOVIColorMetadata, signal_eotf)); +} + +/* Tries to re-use the static ext blocks. May reorder `ext->dm_static` */ +static int try_reuse_ext(DOVIExt *ext, const AVDOVIMetadata *metadata) +{ +int i, j, idx = 0; + +for (i = 0; i < metadata->num_ext_blocks; i++) { +const AVDOVIDmData *dm = av_dovi_get_ext(metadata, i); +if (!ff_dovi_rpu_extension_is_static(dm->level)) +continue; + +/* Find the first matching ext block and move it to [idx] */ +for (j = idx; j < ext->num_static; j++) { +if (!memcmp(&ext->dm_static[j], dm, sizeof(*dm))) { +if (j != idx) +FFSWAP(AVDOVIDmData, ext->dm_static[j], ext->dm_static[idx]); +idx++; +break; +} +} + +if (j == ext->num_static) { +/* Found no matching ext block */ +return 0; +} +} + +/* If idx is less than ext->num_static, then there are extra unmatched + * ext blocks inside ext->dm_static */ +return idx == ext->num_static; +} + static inline void put_ue_coef(PutBitContext *pb, const AVDOVIRpuDataHeader *hdr, uint64_t coef) { @@ -498,7 +554,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, const AVDOVIDataMapping *mapping; const AVDOVIColorMetadata *color; int vdr_dm_metadata_present, vdr_rpu_id, use_prev_vdr_rpu, profile, -buffer_size, rpu_size, pad, zero_run; +buffer_size, rpu_size, pad, zero_run, dm_compression; int num_ext_blocks_v1, num_ext_blocks_v2; int dv_md_compression = s->cfg.dv_md_compression; uint32_t crc; @@ -514,6 +570,11 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, color = av_dovi_get_color(metadata); av_assert0(s->cfg.dv_profile); +if (!(flags & FF_DOVI_COMPRESS_RPU)) +dv_md_compression = AV_DOVI_COMPRESSION_NONE; +else if (dv_md_compression == AV_DOVI_COMPRESSION_RESERVED) +return AVERROR(EINVAL); + if (hdr->rpu_type != 2) { av_log(s->logctx, AV_LOG_ERROR, "Unhandled RPU type %"PRIu8"\n", hdr->rpu_type); @@ -555,9 +616,34 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, } } +if (metadata->num_ext_blocks && !s->ext_blocks) { +s->ext_blocks = ff_refstruct_allocz(sizeof(*s->ext_blocks)); +if (!s->ext_blocks) +return AVERROR(ENOMEM); +} + +vdr_dm_metadata_present = memcmp(color, &ff_dovi_color_default, sizeof(*color)); +if (metadata->num_ext_blocks) +vdr_dm_metadata_present = 1; + +if (vdr_dm_metadata_present && !s->dm) { +s->dm = ff_refstruct_allocz(sizeof(AVDOVIColorMetadata)); +if (!s->dm) +return AVERROR(ENOMEM); +} + +dm_compression = 0; +if (dv_md_compression != AV_DOVI_COMPRESSION_NONE) { +if (!cmp_dm_level0(s->dm, color) && try_reuse_ext(s->ext_blocks, metadata)) +dm_compression = 1; +} + num_ext_blocks_v1 = num_ext_blocks_v2 = 0; for (int i = 0; i < metadata->num_ext_blocks; i++) {
[FFmpeg-devel] [PATCH 21/22] avcodec/libsvtav1: raise strictness of missing DV error
From: Niklas Haas While this is technically a spec violation, the result is still decodable (and will look perfectly fine to clients ignoring Dolby Vision metadata). It will also only happen in garbage in, garbage out scenarios. --- libavcodec/libsvtav1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c index e7b12fb488..4c91750fbe 100644 --- a/libavcodec/libsvtav1.c +++ b/libavcodec/libsvtav1.c @@ -551,10 +551,10 @@ static int eb_send_frame(AVCodecContext *avctx, const AVFrame *frame) } else if (svt_enc->dovi.cfg.dv_profile) { av_log(avctx, AV_LOG_ERROR, "Dolby Vision enabled, but received frame " "without AV_FRAME_DATA_DOVI_METADATA\n"); -return AVERROR_INVALIDDATA; +if (avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT) +return AVERROR_INVALIDDATA; } - svt_ret = svt_av1_enc_send_picture(svt_enc->svt_handle, headerPtr); if (svt_ret != EB_ErrorNone) return svt_print_error(avctx, svt_ret, "Error sending a frame to encoder"); -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 07/22] avcodec/dovi_rpuenc: make encapsulation optional
From: Niklas Haas And move the choice of desired container to `flags`. This is needed to handle differing API requirements (e.g. libx265 requires the NAL RBSP, but CBS BSF requires the unescaped bytes). --- libavcodec/dovi_rpu.h| 16 ++-- libavcodec/dovi_rpuenc.c | 22 ++ libavcodec/libaomenc.c | 3 ++- libavcodec/libsvtav1.c | 3 ++- libavcodec/libx265.c | 2 +- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h index 65a4529106..226a769bff 100644 --- a/libavcodec/dovi_rpu.h +++ b/libavcodec/dovi_rpu.h @@ -123,16 +123,20 @@ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame); */ int ff_dovi_configure(DOVIContext *s, AVCodecContext *avctx); +enum { +FF_DOVI_WRAP_NAL= 1 << 0, ///< wrap inside NAL RBSP +FF_DOVI_WRAP_T35= 1 << 1, ///< wrap inside T.35+EMDF +}; + /** - * Synthesize a Dolby Vision RPU reflecting the current state. Note that this - * assumes all previous calls to `ff_dovi_rpu_generate` have been appropriately - * signalled, i.e. it will not re-send already transmitted redundant data. + * Synthesize a Dolby Vision RPU reflecting the current state. By default, the + * RPU is not encapsulated (see `flags` for more options). Note that this + * assumes all previous calls to `ff_dovi_rpu_generate` have been + * appropriately signalled, i.e. it will not re-send already transmitted + * redundant data. * * Mutates the internal state of DOVIContext to reflect the change. * Returns 0 or a negative error code. - * - * This generates a fully formed RPU ready for inclusion in the bitstream, - * including the EMDF header (profile 10) or NAL encapsulation (otherwise). */ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, int flags, uint8_t **out_rpu, int *out_size); diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c index e1a70be42d..73db9437a0 100644 --- a/libavcodec/dovi_rpuenc.c +++ b/libavcodec/dovi_rpuenc.c @@ -713,9 +713,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, flush_put_bits(pb); rpu_size = put_bytes_output(pb); -switch (s->cfg.dv_profile) { -case 10: -/* AV1 uses T.35 OBU with EMDF header */ +if (flags & FF_DOVI_WRAP_T35) { *out_rpu = av_malloc(rpu_size + 15); if (!*out_rpu) return AVERROR(ENOMEM); @@ -742,10 +740,8 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, flush_put_bits(pb); *out_size = put_bytes_output(pb); return 0; - -case 5: -case 8: -*out_rpu = dst = av_malloc(1 + rpu_size * 3 / 2); /* worst case */ +} else if (flags & FF_DOVI_WRAP_NAL) { +*out_rpu = dst = av_malloc(4 + rpu_size * 3 / 2); /* worst case */ if (!*out_rpu) return AVERROR(ENOMEM); *dst++ = 25; /* NAL prefix */ @@ -768,10 +764,12 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, } *out_size = dst - *out_rpu; return 0; - -default: -/* Should be unreachable */ -av_assert0(0); -return AVERROR_BUG; +} else { +/* Return intermediate buffer directly */ +*out_rpu = s->rpu_buf; +*out_size = rpu_size; +s->rpu_buf = NULL; +s->rpu_buf_sz = 0; +return 0; } } diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c index aa51c89e29..fd9bea2505 100644 --- a/libavcodec/libaomenc.c +++ b/libavcodec/libaomenc.c @@ -1294,7 +1294,8 @@ FF_ENABLE_DEPRECATION_WARNINGS const AVDOVIMetadata *metadata = (const AVDOVIMetadata *)sd->data; uint8_t *t35; int size; -if ((res = ff_dovi_rpu_generate(&ctx->dovi, metadata, 0, &t35, &size)) < 0) +if ((res = ff_dovi_rpu_generate(&ctx->dovi, metadata, FF_DOVI_WRAP_T35, +&t35, &size)) < 0) return res; res = aom_img_add_metadata(rawimg, OBU_METADATA_TYPE_ITUT_T35, t35, size, AOM_MIF_ANY_FRAME); diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c index b6db63fd7a..e7b12fb488 100644 --- a/libavcodec/libsvtav1.c +++ b/libavcodec/libsvtav1.c @@ -541,7 +541,8 @@ static int eb_send_frame(AVCodecContext *avctx, const AVFrame *frame) const AVDOVIMetadata *metadata = (const AVDOVIMetadata *)sd->data; uint8_t *t35; int size; -if ((ret = ff_dovi_rpu_generate(&svt_enc->dovi, metadata, 0, &t35, &size)) < 0) +if ((ret = ff_dovi_rpu_generate(&svt_enc->dovi, metadata, FF_DOVI_WRAP_T35, +&t35, &size)) < 0) return ret; ret = svt_add_metadata(headerPtr, EB_AV1_METADATA_TYPE_ITUT_T35, t35, size); av_free(t35); diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c
[FFmpeg-devel] [PATCH 06/22] avcodec/dovi_rpuenc: add `flags` to ff_dovi_rpu_generate()
From: Niklas Haas Will be used to control compression, encapsulation etc. --- libavcodec/dovi_rpu.h| 2 +- libavcodec/dovi_rpuenc.c | 2 +- libavcodec/libaomenc.c | 2 +- libavcodec/libsvtav1.c | 2 +- libavcodec/libx265.c | 3 ++- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h index 205d16ffbc..65a4529106 100644 --- a/libavcodec/dovi_rpu.h +++ b/libavcodec/dovi_rpu.h @@ -135,7 +135,7 @@ int ff_dovi_configure(DOVIContext *s, AVCodecContext *avctx); * including the EMDF header (profile 10) or NAL encapsulation (otherwise). */ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, - uint8_t **out_rpu, int *out_size); + int flags, uint8_t **out_rpu, int *out_size); /*** diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c index 2a6131eff5..e1a70be42d 100644 --- a/libavcodec/dovi_rpuenc.c +++ b/libavcodec/dovi_rpuenc.c @@ -435,7 +435,7 @@ static void generate_ext_v2(PutBitContext *pb, const AVDOVIDmData *dm) } int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, - uint8_t **out_rpu, int *out_size) + int flags, uint8_t **out_rpu, int *out_size) { PutBitContext *pb = &(PutBitContext){0}; const AVDOVIRpuDataHeader *hdr; diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c index dec74ebecd..aa51c89e29 100644 --- a/libavcodec/libaomenc.c +++ b/libavcodec/libaomenc.c @@ -1294,7 +1294,7 @@ FF_ENABLE_DEPRECATION_WARNINGS const AVDOVIMetadata *metadata = (const AVDOVIMetadata *)sd->data; uint8_t *t35; int size; -if ((res = ff_dovi_rpu_generate(&ctx->dovi, metadata, &t35, &size)) < 0) +if ((res = ff_dovi_rpu_generate(&ctx->dovi, metadata, 0, &t35, &size)) < 0) return res; res = aom_img_add_metadata(rawimg, OBU_METADATA_TYPE_ITUT_T35, t35, size, AOM_MIF_ANY_FRAME); diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c index 2fef8c8971..b6db63fd7a 100644 --- a/libavcodec/libsvtav1.c +++ b/libavcodec/libsvtav1.c @@ -541,7 +541,7 @@ static int eb_send_frame(AVCodecContext *avctx, const AVFrame *frame) const AVDOVIMetadata *metadata = (const AVDOVIMetadata *)sd->data; uint8_t *t35; int size; -if ((ret = ff_dovi_rpu_generate(&svt_enc->dovi, metadata, &t35, &size)) < 0) +if ((ret = ff_dovi_rpu_generate(&svt_enc->dovi, metadata, 0, &t35, &size)) < 0) return ret; ret = svt_add_metadata(headerPtr, EB_AV1_METADATA_TYPE_ITUT_T35, t35, size); av_free(t35); diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c index 0dc7ab6eeb..4302c3d587 100644 --- a/libavcodec/libx265.c +++ b/libavcodec/libx265.c @@ -783,7 +783,8 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, sd = av_frame_get_side_data(pic, AV_FRAME_DATA_DOVI_METADATA); if (ctx->dovi.cfg.dv_profile && sd) { const AVDOVIMetadata *metadata = (const AVDOVIMetadata *)sd->data; -ret = ff_dovi_rpu_generate(&ctx->dovi, metadata, &x265pic.rpu.payload, +ret = ff_dovi_rpu_generate(&ctx->dovi, metadata, 0, + &x265pic.rpu.payload, &x265pic.rpu.payloadSize); if (ret < 0) { free_picture(ctx, &x265pic); -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 09/22] avcodec/dovi_rpu: add ff_dovi_get_metadata()
From: Niklas Haas Provides direct access to the AVDOVIMetadata without having to attach it to a frame. --- libavcodec/dovi_rpu.h| 9 + libavcodec/dovi_rpudec.c | 40 +++- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h index e2e7635cfb..4eb4bc0873 100644 --- a/libavcodec/dovi_rpu.h +++ b/libavcodec/dovi_rpu.h @@ -108,8 +108,17 @@ void ff_dovi_ctx_flush(DOVIContext *s); int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, int err_recognition); +/** + * Get the decoded AVDOVIMetadata. Ownership passes to the caller. + * + * Returns the size of *out_metadata, a negative error code, or 0 if no + * metadata is available to return. + */ +int ff_dovi_get_metadata(DOVIContext *s, AVDOVIMetadata **out_metadata); + /** * Attach the decoded AVDOVIMetadata as side data to an AVFrame. + * Returns 0 or a negative error code. */ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame); diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c index bf6e5075d1..0ddc923539 100644 --- a/libavcodec/dovi_rpudec.c +++ b/libavcodec/dovi_rpudec.c @@ -30,10 +30,8 @@ #include "get_bits.h" #include "refstruct.h" -int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame) +int ff_dovi_get_metadata(DOVIContext *s, AVDOVIMetadata **out_metadata) { -AVFrameSideData *sd; -AVBufferRef *buf; AVDOVIMetadata *dovi; size_t dovi_size, ext_sz; @@ -44,7 +42,32 @@ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame) if (!dovi) return AVERROR(ENOMEM); -buf = av_buffer_create((uint8_t *) dovi, dovi_size, NULL, NULL, 0); +/* Copy only the parts of these structs known to us at compiler-time. */ +#define COPY(t, a, b, last) memcpy(a, b, offsetof(t, last) + sizeof((b)->last)) +COPY(AVDOVIRpuDataHeader, av_dovi_get_header(dovi), &s->header, ext_mapping_idc_5_7); +COPY(AVDOVIDataMapping, av_dovi_get_mapping(dovi), s->mapping, nlq_pivots); +COPY(AVDOVIColorMetadata, av_dovi_get_color(dovi), s->color, source_diagonal); +ext_sz = FFMIN(sizeof(AVDOVIDmData), dovi->ext_block_size); +for (int i = 0; i < s->num_ext_blocks; i++) +memcpy(av_dovi_get_ext(dovi, i), &s->ext_blocks[i], ext_sz); +dovi->num_ext_blocks = s->num_ext_blocks; + +*out_metadata = dovi; +return dovi_size; +} + +int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame) +{ +AVFrameSideData *sd; +AVDOVIMetadata *dovi; +AVBufferRef *buf; +int size; + +size = ff_dovi_get_metadata(s, &dovi); +if (size <= 0) +return size; + +buf = av_buffer_create((uint8_t *) dovi, size, NULL, NULL, 0); if (!buf) { av_free(dovi); return AVERROR(ENOMEM); @@ -56,15 +79,6 @@ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame) return AVERROR(ENOMEM); } -/* Copy only the parts of these structs known to us at compiler-time. */ -#define COPY(t, a, b, last) memcpy(a, b, offsetof(t, last) + sizeof((b)->last)) -COPY(AVDOVIRpuDataHeader, av_dovi_get_header(dovi), &s->header, ext_mapping_idc_5_7); -COPY(AVDOVIDataMapping, av_dovi_get_mapping(dovi), s->mapping, nlq_pivots); -COPY(AVDOVIColorMetadata, av_dovi_get_color(dovi), s->color, source_diagonal); -ext_sz = FFMIN(sizeof(AVDOVIDmData), dovi->ext_block_size); -for (int i = 0; i < s->num_ext_blocks; i++) -memcpy(av_dovi_get_ext(dovi, i), &s->ext_blocks[i], ext_sz); -dovi->num_ext_blocks = s->num_ext_blocks; return 0; } -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 10/22] avcodec/dovi_rpuenc: add ff_dovi_configure_ext()
From: Niklas Haas More flexible version of ff_dovi_configure() which does not require an AVCodecContext. Usable, for example, inside a bitstream filter. --- libavcodec/dovi_rpu.h| 16 +++- libavcodec/dovi_rpuenc.c | 85 +++- 2 files changed, 72 insertions(+), 29 deletions(-) diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h index 4eb4bc0873..1bbc6ef02c 100644 --- a/libavcodec/dovi_rpu.h +++ b/libavcodec/dovi_rpu.h @@ -26,7 +26,9 @@ #include "libavutil/dovi_meta.h" #include "libavutil/frame.h" + #include "avcodec.h" +#include "codec_par.h" #define DOVI_MAX_DM_ID 15 typedef struct DOVIContext { @@ -125,11 +127,23 @@ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame); /** * Configure the encoder for Dolby Vision encoding. Generates a configuration * record in s->cfg, and attaches it to avctx->coded_side_data. Sets the correct - * profile and compatibility ID based on the tagged AVCodecContext colorspace + * profile and compatibility ID based on the tagged AVCodecParameters colorspace * metadata, and the correct level based on the resolution and tagged framerate. * + * `metadata` should point to the first frame's RPU, if available. If absent, + * auto-detection will be performed, but this can sometimes lead to inaccurate + * results (in particular for HEVC streams with enhancement layers). + * * Returns 0 or a negative error code. */ +int ff_dovi_configure_ext(DOVIContext *s, AVCodecParameters *codecpar, + const AVDOVIMetadata *metadata, + int strict_std_compliance); + +/** + * Helper wrapper around `ff_dovi_configure_ext` which infers the codec + * parameters from an AVCodecContext. + */ int ff_dovi_configure(DOVIContext *s, AVCodecContext *avctx); enum { diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c index 0d4e613a72..ad161809a9 100644 --- a/libavcodec/dovi_rpuenc.c +++ b/libavcodec/dovi_rpuenc.c @@ -52,11 +52,12 @@ static struct { [13] = {7680*4320*120u, 7680, 240, 800}, }; -int ff_dovi_configure(DOVIContext *s, AVCodecContext *avctx) +int ff_dovi_configure_ext(DOVIContext *s, AVCodecParameters *codecpar, + const AVDOVIMetadata *metadata, + int strict_std_compliance) { AVDOVIDecoderConfigurationRecord *cfg; const AVDOVIRpuDataHeader *hdr = NULL; -const AVFrameSideData *sd; int dv_profile, dv_level, bl_compat_id = -1; size_t cfg_size; uint64_t pps; @@ -64,16 +65,13 @@ int ff_dovi_configure(DOVIContext *s, AVCodecContext *avctx) if (!s->enable) goto skip; -sd = av_frame_side_data_get(avctx->decoded_side_data, -avctx->nb_decoded_side_data, AV_FRAME_DATA_DOVI_METADATA); - -if (sd) -hdr = av_dovi_get_header((const AVDOVIMetadata *) sd->data); +if (metadata) +hdr = av_dovi_get_header(metadata); if (s->enable == FF_DOVI_AUTOMATIC && !hdr) goto skip; -switch (avctx->codec_id) { +switch (codecpar->codec_id) { case AV_CODEC_ID_AV1: dv_profile = 10; break; case AV_CODEC_ID_H264: dv_profile = 9; break; case AV_CODEC_ID_HEVC: dv_profile = hdr ? ff_dovi_guess_profile_hevc(hdr) : 8; break; @@ -83,12 +81,12 @@ int ff_dovi_configure(DOVIContext *s, AVCodecContext *avctx) return AVERROR_BUG; } -if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) { +if (strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) { if (dv_profile == 9) { -if (avctx->pix_fmt != AV_PIX_FMT_YUV420P) +if (codecpar->format != AV_PIX_FMT_YUV420P) dv_profile = 0; } else { -if (avctx->pix_fmt != AV_PIX_FMT_YUV420P10) +if (codecpar->format != AV_PIX_FMT_YUV420P10) dv_profile = 0; } } @@ -115,17 +113,17 @@ int ff_dovi_configure(DOVIContext *s, AVCodecContext *avctx) } /* fall through */ case 8: /* HEVC (or AV1) with BL compatibility */ -if (avctx->colorspace == AVCOL_SPC_BT2020_NCL && -avctx->color_primaries == AVCOL_PRI_BT2020 && -avctx->color_trc == AVCOL_TRC_SMPTE2084) { +if (codecpar->color_space == AVCOL_SPC_BT2020_NCL && +codecpar->color_primaries == AVCOL_PRI_BT2020 && +codecpar->color_trc == AVCOL_TRC_SMPTE2084) { bl_compat_id = 1; -} else if (avctx->colorspace == AVCOL_SPC_BT2020_NCL && - avctx->color_primaries == AVCOL_PRI_BT2020 && - avctx->color_trc == AVCOL_TRC_ARIB_STD_B67) { +} else if (codecpar->color_space == AVCOL_SPC_BT2020_NCL && + codecpar->color_primaries == AVCOL_PRI_BT2020 && + codecpar->color_trc == AVCOL_TRC_ARIB_STD_B67) { bl_compat_id = 4; -} else if (avctx->colorspace == AVCOL_SPC_BT709 && - avctx->c
[FFmpeg-devel] [PATCH 08/22] avcodec/dovi_rpuenc: add a flag to enable compression
From: Niklas Haas Keyframes must reset the metadata compression state, so we need to also signal this at rpu generation time. Default to uncompressed, because encoders cannot generally know if a given frame will be a keyframe before they finish encoding, but also cannot retroactively attach the RPU. (Within the confines of current APIs) --- libavcodec/dovi_rpu.h| 1 + libavcodec/dovi_rpuenc.c | 6 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h index 226a769bff..e2e7635cfb 100644 --- a/libavcodec/dovi_rpu.h +++ b/libavcodec/dovi_rpu.h @@ -126,6 +126,7 @@ int ff_dovi_configure(DOVIContext *s, AVCodecContext *avctx); enum { FF_DOVI_WRAP_NAL= 1 << 0, ///< wrap inside NAL RBSP FF_DOVI_WRAP_T35= 1 << 1, ///< wrap inside T.35+EMDF +FF_DOVI_COMPRESS_RPU= 1 << 2, ///< enable compression for this RPU }; /** diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c index 73db9437a0..0d4e613a72 100644 --- a/libavcodec/dovi_rpuenc.c +++ b/libavcodec/dovi_rpuenc.c @@ -444,6 +444,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, int vdr_dm_metadata_present, vdr_rpu_id, use_prev_vdr_rpu, profile, buffer_size, rpu_size, pad, zero_run; int num_ext_blocks_v1, num_ext_blocks_v2; +int dv_md_compression = s->cfg.dv_md_compression; uint32_t crc; uint8_t *dst; if (!metadata) { @@ -463,6 +464,9 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, return AVERROR_INVALIDDATA; } +if (!(flags & FF_DOVI_COMPRESS_RPU)) +dv_md_compression = AV_DOVI_COMPRESSION_NONE; + vdr_rpu_id = mapping->vdr_rpu_id; use_prev_vdr_rpu = 0; @@ -472,7 +476,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, return AVERROR(ENOMEM); } -switch (s->cfg.dv_md_compression) { +switch (dv_md_compression) { case AV_DOVI_COMPRESSION_LIMITED: /* Limited metadata compression requires vdr_rpi_id == 0 */ if (vdr_rpu_id != 0) -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 13/22] avcodec/dovi_rpu: move ext blocks into dedicated struct
From: Niklas Haas Slightly re-organize the logic around extension blocks in order to allow expanding the state tracking in a following commit. --- libavcodec/dovi_rpu.c| 1 - libavcodec/dovi_rpu.h| 9 +++-- libavcodec/dovi_rpudec.c | 35 ++- libavcodec/dovi_rpuenc.c | 16 +--- 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c index b67978403f..5130a9598d 100644 --- a/libavcodec/dovi_rpu.c +++ b/libavcodec/dovi_rpu.c @@ -66,7 +66,6 @@ void ff_dovi_ctx_replace(DOVIContext *s, const DOVIContext *s0) for (int i = 0; i <= DOVI_MAX_DM_ID; i++) ff_refstruct_replace(&s->vdr[i], s0->vdr[i]); ff_refstruct_replace(&s->ext_blocks, s0->ext_blocks); -s->num_ext_blocks = s0->num_ext_blocks; } int ff_dovi_guess_profile_hevc(const AVDOVIRpuDataHeader *hdr) diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h index 24a8353bdc..ed5bfa7b26 100644 --- a/libavcodec/dovi_rpu.h +++ b/libavcodec/dovi_rpu.h @@ -31,6 +31,12 @@ #include "codec_par.h" #define DOVI_MAX_DM_ID 15 + +typedef struct DOVIExt { +AVDOVIDmData dm[AV_DOVI_MAX_EXT_BLOCKS]; +int num_dm; +} DOVIExt; + typedef struct DOVIContext { void *logctx; @@ -70,8 +76,7 @@ typedef struct DOVIContext { * Currently active extension blocks, updates on every ff_dovi_rpu_parse() * or ff_dovi_rpu_generate(). */ -AVDOVIDmData *ext_blocks; -int num_ext_blocks; +DOVIExt *ext_blocks; ///< RefStruct, or NULL if no extension blocks /** * Private fields internal to dovi_rpu.c diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c index 0ddc923539..1650547c80 100644 --- a/libavcodec/dovi_rpudec.c +++ b/libavcodec/dovi_rpudec.c @@ -33,7 +33,7 @@ int ff_dovi_get_metadata(DOVIContext *s, AVDOVIMetadata **out_metadata) { AVDOVIMetadata *dovi; -size_t dovi_size, ext_sz; +size_t dovi_size; if (!s->mapping || !s->color) return 0; /* incomplete dovi metadata */ @@ -47,10 +47,14 @@ int ff_dovi_get_metadata(DOVIContext *s, AVDOVIMetadata **out_metadata) COPY(AVDOVIRpuDataHeader, av_dovi_get_header(dovi), &s->header, ext_mapping_idc_5_7); COPY(AVDOVIDataMapping, av_dovi_get_mapping(dovi), s->mapping, nlq_pivots); COPY(AVDOVIColorMetadata, av_dovi_get_color(dovi), s->color, source_diagonal); -ext_sz = FFMIN(sizeof(AVDOVIDmData), dovi->ext_block_size); -for (int i = 0; i < s->num_ext_blocks; i++) -memcpy(av_dovi_get_ext(dovi, i), &s->ext_blocks[i], ext_sz); -dovi->num_ext_blocks = s->num_ext_blocks; + +if (s->ext_blocks) { +const DOVIExt *ext = s->ext_blocks; +size_t ext_sz = FFMIN(sizeof(AVDOVIDmData), dovi->ext_block_size); +for (int i = 0; i < ext->num_dm; i++) +memcpy(av_dovi_get_ext(dovi, i), &ext->dm[i], ext_sz); +dovi->num_ext_blocks = ext->num_dm; +} *out_metadata = dovi; return dovi_size; @@ -279,20 +283,24 @@ static int parse_ext_v2(DOVIContext *s, GetBitContext *gb, AVDOVIDmData *dm, static int parse_ext_blocks(DOVIContext *s, GetBitContext *gb, int ver) { int num_ext_blocks, ext_block_length, start_pos, parsed_bits, ret; +DOVIExt *ext = s->ext_blocks; num_ext_blocks = get_ue_golomb_31(gb); align_get_bits(gb); -if (s->num_ext_blocks + num_ext_blocks > AV_DOVI_MAX_EXT_BLOCKS) -return AVERROR_INVALIDDATA; -if (!s->ext_blocks) { -s->ext_blocks = ff_refstruct_allocz(sizeof(AVDOVIDmData) * AV_DOVI_MAX_EXT_BLOCKS); -if (!s->ext_blocks) +if (!ext) { +ext = s->ext_blocks = ff_refstruct_allocz(sizeof(*s->ext_blocks)); +if (!ext) return AVERROR(ENOMEM); } while (num_ext_blocks--) { -AVDOVIDmData *dm = &s->ext_blocks[s->num_ext_blocks++]; +AVDOVIDmData *dm; + +if (ext->num_dm >= FF_ARRAY_ELEMS(ext->dm)) +return AVERROR_INVALIDDATA; +dm = &ext->dm[ext->num_dm++]; + ext_block_length = get_ue_golomb_31(gb); dm->level = get_bits(gb, 8); start_pos = get_bits_count(gb); @@ -666,7 +674,8 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, color->source_diagonal = get_bits(gb, 10); /* Parse extension blocks */ -s->num_ext_blocks = 0; +if (s->ext_blocks) +s->ext_blocks->num_dm = 0; if ((ret = parse_ext_blocks(s, gb, 1)) < 0) { ff_dovi_ctx_unref(s); return ret; @@ -680,7 +689,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size, } } else { s->color = &ff_dovi_color_default; -s->num_ext_blocks = 0; +ff_refstruct_unref(&s->ext_blocks); } return 0; diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c index 25e520dd92..667d681c25 100644 --- a/libavcodec/dovi_rpuenc.c +++ b/libavcodec/dovi_rpue
[FFmpeg-devel] [PATCH 11/22] avcodec/dovi_rpuenc: add configuration for compression
From: Niklas Haas In particular, validate that the chosen compression level is compatible with the chosen profile. --- libavcodec/dovi_rpu.h| 1 + libavcodec/dovi_rpuenc.c | 29 - 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h index 1bbc6ef02c..24a8353bdc 100644 --- a/libavcodec/dovi_rpu.h +++ b/libavcodec/dovi_rpu.h @@ -138,6 +138,7 @@ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame); */ int ff_dovi_configure_ext(DOVIContext *s, AVCodecParameters *codecpar, const AVDOVIMetadata *metadata, + enum AVDOVICompression compression, int strict_std_compliance); /** diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c index ad161809a9..25e520dd92 100644 --- a/libavcodec/dovi_rpuenc.c +++ b/libavcodec/dovi_rpuenc.c @@ -54,6 +54,7 @@ static struct { int ff_dovi_configure_ext(DOVIContext *s, AVCodecParameters *codecpar, const AVDOVIMetadata *metadata, + enum AVDOVICompression compression, int strict_std_compliance) { AVDOVIDecoderConfigurationRecord *cfg; @@ -71,6 +72,10 @@ int ff_dovi_configure_ext(DOVIContext *s, AVCodecParameters *codecpar, if (s->enable == FF_DOVI_AUTOMATIC && !hdr) goto skip; +if (compression == AV_DOVI_COMPRESSION_RESERVED || +compression > AV_DOVI_COMPRESSION_EXTENDED) +return AVERROR(EINVAL); + switch (codecpar->codec_id) { case AV_CODEC_ID_AV1: dv_profile = 10; break; case AV_CODEC_ID_H264: dv_profile = 9; break; @@ -138,6 +143,25 @@ int ff_dovi_configure_ext(DOVIContext *s, AVCodecParameters *codecpar, goto skip; } +if (compression != AV_DOVI_COMPRESSION_NONE) { +if (dv_profile < 8 && strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) { +av_log(s->logctx, AV_LOG_ERROR, "Dolby Vision metadata compression " + "is not permitted for profiles 7 and earlier. (dv_profile: %d, " + "compression: %d)\n", dv_profile, compression); +return AVERROR(EINVAL); +} else if (compression == AV_DOVI_COMPRESSION_EXTENDED && + strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { +av_log(s->logctx, AV_LOG_ERROR, "Dolby Vision extended metadata " + "compression is experimental and not supported by " + "devices."); +return AVERROR(EINVAL); +} else if (dv_profile == 8) { +av_log(s->logctx, AV_LOG_WARNING, "Dolby Vision metadata compression " + "for profile 8 is known to be unsupported by many devices, " + "use with caution.\n"); +} +} + pps = codecpar->width * codecpar->height; if (codecpar->framerate.num) { pps = pps * codecpar->framerate.num / codecpar->framerate.den; @@ -191,6 +215,7 @@ int ff_dovi_configure_ext(DOVIContext *s, AVCodecParameters *codecpar, cfg->el_present_flag = 0; cfg->bl_present_flag = 1; cfg->dv_bl_signal_compatibility_id = bl_compat_id; +cfg->dv_md_compression = compression; s->cfg = *cfg; return 0; @@ -219,7 +244,9 @@ int ff_dovi_configure(DOVIContext *s, AVCodecContext *avctx) if (sd) metadata = (const AVDOVIMetadata *) sd->data; -ret = ff_dovi_configure_ext(s, codecpar, metadata, avctx->strict_std_compliance); +/* Current encoders cannot handle metadata compression during encoding */ +ret = ff_dovi_configure_ext(s, codecpar, metadata, AV_DOVI_COMPRESSION_NONE, +avctx->strict_std_compliance); if (ret < 0) goto fail; -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] aarch64: Implement support for elf_aux_info(3) on FreeBSD and OpenBSD
On Sun, 28 Jul 2024, Rémi Denis-Courmont wrote: Le 28 juillet 2024 07:37:51 GMT+03:00, Brad Smith a écrit : On 2024-07-26 7:56 a.m., Rémi Denis-Courmont wrote: Le 26 juillet 2024 13:58:34 GMT+03:00, Brad Smith a écrit : aarch64: Implement support for elf_aux_info(3) on FreeBSD and OpenBSD FreeBSD 12.0+, OpenBSD -current and what will be OpenBSD 7.6 support elf_aux_info(3). Signed-off-by: Brad Smith --- configure | 2 ++ libavutil/aarch64/cpu.c | 23 ++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/configure b/configure index f6f5c29fea..e80b549582 100755 --- a/configure +++ b/configure @@ -2366,6 +2366,7 @@ SYSTEM_FUNCS=" clock_gettime closesocket CommandLineToArgvW +elf_aux_info fcntl getaddrinfo getauxval @@ -6565,6 +6566,7 @@ check_func_headers mach/mach_time.h mach_absolute_time check_func_headers stdlib.h getenv check_func_headers sys/stat.h lstat check_func_headers sys/auxv.h getauxval +check_func_headers sys/auxv.h elf_aux_info check_func_headers sys/sysctl.h sysctlbyname check_func_headers windows.h GetModuleHandle diff --git a/libavutil/aarch64/cpu.c b/libavutil/aarch64/cpu.c index cfa9306663..05272b4db4 100644 --- a/libavutil/aarch64/cpu.c +++ b/libavutil/aarch64/cpu.c @@ -42,6 +42,27 @@ static int detect_flags(void) return flags; } +#elif (defined(__FreeBSD__) || defined(__OpenBSD__)) && HAVE_ELF_AUX_INFO +#include +#include + +static int detect_flags(void) +{ +int flags = 0; + +unsigned long hwcap = 0; +elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap); +unsigned long hwcap2 = 0; +elf_aux_info(AT_HWCAP2, &hwcap2, sizeof hwcap2); + +if (hwcap & HWCAP_ASIMDDP) +flags |= AV_CPU_FLAG_DOTPROD; +if (hwcap2 & HWCAP2_I8MM) +flags |= AV_CPU_FLAG_I8MM; + +return flags; +} + Can't getauxval() be implemented with elf_aux_info(), or vice versa? It seems that otherwise the code should be identical to that from Linux. QEMU has qemu_getauxval() for example as a wrapper. I will be using this elsewhere for arm, ppc and riscv. I could split this up, but I am not sure where to place such a function. I don't personally have a strong opinion on the details, I just don't fancy unnecessary duplication. I don't have a very strong opinion on it either, but if it's reasonable to make this a static inline function in a header, it could e.g. be in the compat directory, or just as a private header in libavutil. // Martin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 2/2] lavc/d3d12va_encode: trim header alignment at output
Tong Wu: >Subject: [FFmpeg-devel][PATCH 2/2] lavc/d3d12va_encode: trim header >alignment at output > >It is d3d12va's requirement that the FrameStartOffset must be aligned as per >hardware limitation. However, we could trim this alignment at output to reduce >coded size. A aligned_header_size is added to D3D12VAEncodePicture. > >Signed-off-by: Tong Wu >--- > libavcodec/d3d12va_encode.c | 18 -- >libavcodec/d3d12va_encode.h | 1 + > 2 files changed, 13 insertions(+), 6 deletions(-) > >diff --git a/libavcodec/d3d12va_encode.c b/libavcodec/d3d12va_encode.c index >9f7a42911e..9ee9da41e3 100644 >--- a/libavcodec/d3d12va_encode.c >+++ b/libavcodec/d3d12va_encode.c >@@ -308,9 +308,9 @@ static int d3d12va_encode_issue(AVCodecContext *avctx, > } > > pic->header_size = (int)bit_len / 8; >-pic->header_size = pic->header_size % ctx- >>req.CompressedBitstreamBufferAccessAlignment ? >- FFALIGN(pic->header_size, ctx- >>req.CompressedBitstreamBufferAccessAlignment) : >- pic->header_size; >+pic->aligned_header_size = pic->header_size % ctx- >>req.CompressedBitstreamBufferAccessAlignment ? >+ FFALIGN(pic->header_size, ctx- >>req.CompressedBitstreamBufferAccessAlignment) : >+ pic->header_size; > > hr = ID3D12Resource_Map(pic->output_buffer, 0, NULL, (void **)&ptr); > if (FAILED(hr)) { >@@ -318,7 +318,7 @@ static int d3d12va_encode_issue(AVCodecContext *avctx, > goto fail; > } > >-memcpy(ptr, data, pic->header_size); >+memcpy(ptr, data, pic->aligned_header_size); > ID3D12Resource_Unmap(pic->output_buffer, 0, NULL); > } > >@@ -344,10 +344,10 @@ static int d3d12va_encode_issue(AVCodecContext >*avctx, > > input_args.PictureControlDesc.PictureControlCodecData = pic->pic_ctl; > input_args.PictureControlDesc.ReferenceFrames = d3d12_refs; >-input_args.CurrentFrameBitstreamMetadataSize = pic->header_size; >+input_args.CurrentFrameBitstreamMetadataSize = pic- >>aligned_header_size; > > output_args.Bitstream.pBuffer= > pic->output_buffer; >-output_args.Bitstream.FrameStartOffset = >pic->header_size; >+output_args.Bitstream.FrameStartOffset = pic- >>aligned_header_size; > output_args.ReconstructedPicture.pReconstructedPicture = pic- >>recon_surface->texture; > output_args.ReconstructedPicture.ReconstructedPictureSubresource = 0; > output_args.EncoderOutputMetadata.pBuffer= pic- >>encoded_metadata; >@@ -663,6 +663,12 @@ static int >d3d12va_encode_get_coded_data(AVCodecContext *avctx, > goto end; > ptr = pkt->data; > >+memcpy(ptr, mapped_data, pic->header_size); >+ >+ptr += pic->header_size; >+mapped_data += pic->aligned_header_size; >+total_size -= pic->header_size; >+ > memcpy(ptr, mapped_data, total_size); > > ID3D12Resource_Unmap(pic->output_buffer, 0, NULL); diff --git >a/libavcodec/d3d12va_encode.h b/libavcodec/d3d12va_encode.h index >1a0abc5bd0..51440428e4 100644 >--- a/libavcodec/d3d12va_encode.h >+++ b/libavcodec/d3d12va_encode.h >@@ -43,6 +43,7 @@ typedef struct D3D12VAEncodePicture { > FFHWBaseEncodePicture base; > > int header_size; >+int aligned_header_size; > > AVD3D12VAFrame *input_surface; > AVD3D12VAFrame *recon_surface; >-- >2.45.1.windows.1 The first patch in this patchset has been merged earlier. Will merge this patch if there's no more comment. -Tong ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v3 1/2] libavformat/vapoursynth: Update to API version 4, load library at runtime
On 2024-07-23 16:51, Stefan Oltmanns via ffmpeg-devel wrote: this is revised patch, this is the first part that just updates to the API v4 of VapourSynth. Changes in API v4: -All functions previously in header are now part of the "vssapi" object -Renames of different types and functions -YCoCg is not treated as different format to YUV anymore -Some pointers to arrays are now arrays inside a struct. From 164a440ffbb5951ca38bfff56e7b62bd677d1f52 Mon Sep 17 00:00:00 2001 From: Stefan Oltmanns Date: Tue, 23 Jul 2024 16:15:36 +0200 Subject: [PATCH 1/2] avformat/vapoursynth: Update to API version 4 Signed-off-by: Stefan Oltmanns --- configure | 2 +- libavformat/vapoursynth.c | 84 +-- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/configure b/configure index f6f5c29fea..c50b5ad4b4 100755 --- a/configure +++ b/configure @@ -7085,7 +7085,7 @@ enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/r { enabled libdrm || die "ERROR: rkmpp requires --enable-libdrm"; } } -enabled vapoursynth && require_pkg_config vapoursynth "vapoursynth-script >= 42" VSScript.h vsscript_init +enabled vapoursynth && require_pkg_config vapoursynth "vapoursynth-script >= 55" VSScript4.h getVSScriptAPI if enabled gcrypt; then diff --git a/libavformat/vapoursynth.c b/libavformat/vapoursynth.c index 8a2519e19a..ce15f68180 100644 --- a/libavformat/vapoursynth.c +++ b/libavformat/vapoursynth.c @@ -25,8 +25,7 @@ #include -#include -#include +#include #include "libavutil/avassert.h" #include "libavutil/avstring.h" @@ -41,6 +40,7 @@ #include "internal.h" struct VSState { +const VSSCRIPTAPI *vssapi; VSScript *vss; }; @@ -49,10 +49,10 @@ typedef struct VSContext { AVBufferRef *vss_state; +const VSSCRIPTAPI *vssapi; const VSAPI *vsapi; -VSCore *vscore; -VSNodeRef *outnode; +VSNode *outnode; int is_cfr; int current_frame; @@ -75,8 +75,7 @@ static void free_vss_state(void *opaque, uint8_t *data) struct VSState *vss = opaque; if (vss->vss) { -vsscript_freeScript(vss->vss); -vsscript_finalize(); +vss->vssapi->freeScript(vss->vss); } } @@ -90,7 +89,6 @@ static av_cold int read_close_vs(AVFormatContext *s) av_buffer_unref(&vs->vss_state); vs->vsapi = NULL; -vs->vscore = NULL; vs->outnode = NULL; return 0; @@ -106,7 +104,7 @@ static av_cold int is_native_endian(enum AVPixelFormat pixfmt) return pd && (!!HAVE_BIGENDIAN == !!(pd->flags & AV_PIX_FMT_FLAG_BE)); } -static av_cold enum AVPixelFormat match_pixfmt(const VSFormat *vsf, int c_order[4]) +static av_cold enum AVPixelFormat match_pixfmt(const VSVideoFormat *vsf, int c_order[4]) { static const int yuv_order[4] = {0, 1, 2, 0}; static const int rgb_order[4] = {1, 2, 0, 0}; @@ -128,13 +126,12 @@ static av_cold enum AVPixelFormat match_pixfmt(const VSFormat *vsf, int c_order[ pd->log2_chroma_h != vsf->subSamplingH) continue; -is_rgb = vsf->colorFamily == cmRGB; +is_rgb = vsf->colorFamily == cfRGB; if (is_rgb != !!(pd->flags & AV_PIX_FMT_FLAG_RGB)) continue; -is_yuv = vsf->colorFamily == cmYUV || - vsf->colorFamily == cmYCoCg || - vsf->colorFamily == cmGray; +is_yuv = vsf->colorFamily == cfYUV || + vsf->colorFamily == cfGray; if (!is_rgb && !is_yuv) continue; @@ -176,15 +173,30 @@ static av_cold int read_header_vs(AVFormatContext *s) int64_t sz = avio_size(pb); char *buf = NULL; char dummy; +char vsfmt[32]; const VSVideoInfo *info; struct VSState *vss_state; int err = 0; +if (!(vs->vssapi = getVSScriptAPI(VSSCRIPT_API_VERSION))) { +av_log(s, AV_LOG_ERROR, "Failed to initialize VSScript (possibly PYTHONPATH not set).\n"); +err = AVERROR_EXTERNAL; +goto done; +} + +if (!(vs->vsapi = vs->vssapi->getVSAPI(VAPOURSYNTH_API_VERSION))) { +av_log(s, AV_LOG_ERROR, "Could not get VSAPI. " +"Check VapourSynth installation.\n"); +err = AVERROR_EXTERNAL; +goto done; +} + vss_state = av_mallocz(sizeof(*vss_state)); if (!vss_state) { err = AVERROR(ENOMEM); goto done; } +vss_state->vssapi = vs->vssapi; vs->vss_state = av_buffer_create(NULL, 0, free_vss_state, vss_state, 0); if (!vs->vss_state) { @@ -193,16 +205,9 @@ static av_cold int read_header_vs(AVFormatContext *s) goto done; } -if (!vsscript_init()) { -av_log(s, AV_LOG_ERROR, "Failed to initialize VSScript (possibly PYTHONPATH not set).\n"); -err = AVERROR_EXTERNAL; -goto done; -} - -
Re: [FFmpeg-devel] [PATCH v3 2/2] libavformat/vapoursynth: Update to API version 4, load library at runtime
On 2024-07-23 16:59, Stefan Oltmanns via ffmpeg-devel wrote: This is the second part for loading the library at runtime, changes compared to previous patch revisions: -No atexit anymore -No global states anymore -Moved the registry read for Windows from a separate function inside the function to load the dynamic library and simplified it, reducing the amount windows-specific code. Tested with 2 VapourSynth inputs on these platforms, no problems and clean exit: -Linux x86_64 (Ubuntu 22.04) -Windows 10 x86_64 -macOS 14 aarch64 From 6a8e8b7d5bfcfb8eb3cb24ea1f7e14ca117882c4 Mon Sep 17 00:00:00 2001 From: Stefan Oltmanns Date: Tue, 23 Jul 2024 16:19:46 +0200 Subject: [PATCH 2/2] avformat/vapoursynth: load library at runtime Signed-off-by: Stefan Oltmanns --- configure | 2 +- libavformat/vapoursynth.c | 65 +-- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/configure b/configure index c50b5ad4b4..1b6670505a 100755 --- a/configure +++ b/configure @@ -7085,7 +7085,7 @@ enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/r { enabled libdrm || die "ERROR: rkmpp requires --enable-libdrm"; } } -enabled vapoursynth && require_pkg_config vapoursynth "vapoursynth-script >= 55" VSScript4.h getVSScriptAPI +enabled vapoursynth && require_headers "vapoursynth/VSScript4.h vapoursynth/VapourSynth4.h" if enabled gcrypt; then diff --git a/libavformat/vapoursynth.c b/libavformat/vapoursynth.c index ce15f68180..ad1d6eac61 100644 --- a/libavformat/vapoursynth.c +++ b/libavformat/vapoursynth.c @@ -25,7 +25,7 @@ #include -#include +#include #include "libavutil/avassert.h" #include "libavutil/avstring.h" @@ -39,11 +39,26 @@ #include "demux.h" #include "internal.h" +/* Platform-specific directives. */ +#ifdef _WIN32 + #include + #include "compat/w32dlfcn.h" + #include "libavutil/wchar_filename.h" + #undef EXTERN_C + #define VSSCRIPT_LIB "VSScript.dll" +#else + #include + #define VSSCRIPT_NAME "libvapoursynth-script" + #define VSSCRIPT_LIB VSSCRIPT_NAME SLIBSUF +#endif + struct VSState { const VSSCRIPTAPI *vssapi; VSScript *vss; }; +typedef const VSSCRIPTAPI *(*VSScriptGetAPIFunc)(int version); + typedef struct VSContext { const AVClass *class; @@ -51,6 +66,7 @@ typedef struct VSContext { const VSSCRIPTAPI *vssapi; const VSAPI *vsapi; +void *vslibrary; VSNode *outnode; int is_cfr; @@ -70,6 +86,40 @@ static const AVOption options[] = { {NULL} }; +static av_cold void* vs_load_library(VSScriptGetAPIFunc *get_vssapi) +{ +void *vslibrary = NULL; +#ifdef _WIN32 +const HKEY hkeys[] = {HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE}; +LONG r; +WCHAR vss_path[512]; +DWORD buf_size = sizeof(vss_path) - 2; +char *vss_path_utf8; +int i; + +for (i = 0; i < sizeof(hkeys); i++) { FF_ARRAY_ELEMS(hkeys) +if ((r = RegGetValueW(hkeys[i], L"SOFTWARE\\VapourSynth", + L"VSScriptDLL", RRF_RT_REG_SZ, NULL, + &vss_path, &buf_size)) == ERROR_SUCCESS) +break; +} +if (r == ERROR_SUCCESS && wchartoutf8(vss_path, &vss_path_utf8) == 0) { +vslibrary = dlopen(vss_path_utf8, RTLD_NOW | RTLD_GLOBAL); I think calling win32_dlopen() with a full path will be problematic for systems without KB2533623. win32_dlopen() might need to be fixed in a separate patch. [...] Regards, Ramiro ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 1/2 v2] avformat/avisynth: remove atexit() handler
On Fri, Jul 19, 2024 at 7:51 PM Stephen Hutchinson wrote: > > The atexit() handler in the avisynth demuxer was added because > there was a conflict in AvxSynth that arose due to their use > of C++ global objects, particularly in relation to having > added a logging function relying on log4cpp. > > This conflict was responsible for causing a segfault on exit. > It did not affect Windows with the (at the time) upstream > AviSynth 2.5 and 2.6, nor does it affect AviSynth+. > > Unfortunately, none of this was actually shielded by ifdefs > indicating the fact it was only needed for AvxSynth, so four > years ago when AviSynth+ replaced AvxSynth as the handler > for AviSynth scripts on Unix-like OSes, the fact that the > atexit handler was no longer necessary was overlooked. > > Signed-off-by: Stephen Hutchinson > --- > Changes compared to v1: > * Added missing dlclose invocation to read_close > > libavformat/avisynth.c | 46 +- > 1 file changed, 1 insertion(+), 45 deletions(-) > > diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c > index 625bdf7e3a..26747671c0 100644 > --- a/libavformat/avisynth.c > +++ b/libavformat/avisynth.c > @@ -115,9 +115,6 @@ typedef struct AviSynthContext { > int error; > > uint32_t flags; > - > -/* Linked list pointers. */ > -struct AviSynthContext *next; > } AviSynthContext; > > static const int avs_planes_packed[1] = { 0 }; > @@ -133,15 +130,7 @@ static const int avs_planes_rgba[4] = { AVS_PLANAR_G, > AVS_PLANAR_B, > > static AVMutex avisynth_mutex = AV_MUTEX_INITIALIZER; > > -/* A conflict between C++ global objects, atexit, and dynamic loading > requires > - * us to register our own atexit handler to prevent double freeing. */ > static AviSynthLibrary avs_library; > -static int avs_atexit_called= 0; > - > -/* Linked list of AviSynthContexts. An atexit handler destroys this list. */ > -static AviSynthContext *avs_ctx_list = NULL; > - > -static av_cold void avisynth_atexit_handler(void); > > static av_cold int avisynth_load_library(void) > { > @@ -185,7 +174,6 @@ static av_cold int avisynth_load_library(void) > LOAD_AVS_FUNC(avs_get_env_property, 1); > #undef LOAD_AVS_FUNC > > -atexit(avisynth_atexit_handler); > return 0; > > fail: > @@ -214,30 +202,11 @@ static av_cold int > avisynth_context_create(AVFormatContext *s) > } > } > > -if (!avs_ctx_list) { > -avs_ctx_list = avs; > -} else { > -avs->next= avs_ctx_list; > -avs_ctx_list = avs; > -} > - > return 0; > } > > static av_cold void avisynth_context_destroy(AviSynthContext *avs) > { > -if (avs_atexit_called) > -return; > - > -if (avs == avs_ctx_list) { > -avs_ctx_list = avs->next; > -} else { > -AviSynthContext *prev = avs_ctx_list; > -while (prev->next != avs) > -prev = prev->next; > -prev->next = avs->next; > -} > - > if (avs->clip) { > avs_library.avs_release_clip(avs->clip); > avs->clip = NULL; > @@ -248,20 +217,6 @@ static av_cold void > avisynth_context_destroy(AviSynthContext *avs) > } > } > > -static av_cold void avisynth_atexit_handler(void) > -{ > -AviSynthContext *avs = avs_ctx_list; > - > -while (avs) { > -AviSynthContext *next = avs->next; > -avisynth_context_destroy(avs); > -avs = next; > -} > -dlclose(avs_library.library); > - > -avs_atexit_called = 1; > -} > - > /* Create AVStream from audio and video data. */ > static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) > { > @@ -1134,6 +1089,7 @@ static av_cold int avisynth_read_close(AVFormatContext > *s) > return AVERROR_UNKNOWN; > > avisynth_context_destroy(s->priv_data); > +dlclose(avs_library.library); Maybe it's best to wrap this around an if (avs_library.library). [...] Besides that, the patch looks ok. Ramiro ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2] libavfilter: add PipeWire-based grab
Is it possible to use this without using the portals API and without systemd? That would be much appreciated if so since the portal is not very flexible. As for systemd it would be great to be able to use this on non-systemd platforms. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 2/7] avformat/dvdvideodec: Implement seeking
Hi Marth64, On Sun, Jul 28, 2024 at 3:35 AM Marth64 wrote: > > Player applications can now enjoy seeking while playing back > a title. Accuracy is at the mercy of what libdvdnav offers, > which is currently dvdnav_jump_to_sector_by_time(). > > Signed-off-by: Marth64 > --- > libavformat/dvdvideodec.c | 93 ++- > 1 file changed, 82 insertions(+), 11 deletions(-) > > diff --git a/libavformat/dvdvideodec.c b/libavformat/dvdvideodec.c > index e745165e00..e8301b1173 100644 > --- a/libavformat/dvdvideodec.c > +++ b/libavformat/dvdvideodec.c > @@ -110,6 +110,7 @@ typedef struct DVDVideoPlaybackState { > int in_pgc; /* if our navigator is > in the PGC */ > int in_ps; /* if our navigator is > in the program stream */ > int in_vts; /* if our navigator is > in the VTS */ > +int is_seeking; /* relax navigation path > while seeking */ > int64_t nav_pts;/* PTS according to IFO, > not frame-accurate */ > uint64_tpgc_duration_est; /* estimated duration as > reported by IFO */ > uint64_tpgc_elapsed;/* the elapsed time of > the PGC, cell-relative */ > @@ -722,7 +723,8 @@ static int dvdvideo_play_next_ps_block(AVFormatContext > *s, DVDVideoPlaybackState > > state->in_pgc = 1; > } > -} else if (state->celln >= e_cell->cellN || state->pgn > > cur_pgn) { > +} else if (!state->is_seeking && > + (state->celln >= e_cell->cellN || state->pgn > > cur_pgn)) { > return AVERROR_EOF; > } > > @@ -735,7 +737,7 @@ static int dvdvideo_play_next_ps_block(AVFormatContext > *s, DVDVideoPlaybackState > if (!state->in_pgc) > continue; > > -if ((state->ptt > 0 && state->ptt > cur_ptt) || > +if ((!state->is_seeking && state->ptt > 0 && state->ptt > > cur_ptt) || > (c->opt_chapter_end > 0 && cur_ptt > > c->opt_chapter_end)) { > return AVERROR_EOF; > } > @@ -807,13 +809,15 @@ static int dvdvideo_play_next_ps_block(AVFormatContext > *s, DVDVideoPlaybackState > return AVERROR_INPUT_CHANGED; > } > > -memcpy(buf, &nav_buf, nav_len); > - > if (state->pgn != cur_pgn) > av_log(s, AV_LOG_WARNING, "Unexpected PG change > (expected=%d actual=%d); " >"this could be due to a missed > NAV packet\n", >state->pgn, cur_pgn); > > +memcpy(buf, &nav_buf, nav_len); > + > +state->is_seeking = 0; > + > return nav_len; > case DVDNAV_WAIT: > if (dvdnav_wait_skip(state->dvdnav) != DVDNAV_STATUS_OK) { > @@ -1659,17 +1663,17 @@ static int dvdvideo_read_packet(AVFormatContext *s, > AVPacket *pkt) > } > > av_log(s, AV_LOG_TRACE, "st=%d pts=%" PRId64 " dts=%" PRId64 " " > -"pts_offset=%" PRId64 " first_pts=%" PRId64 "\n", > +"pts_offset=%" PRId64 " first_pts=%" PRId64 " > is_seeking=%d\n", > pkt->stream_index, pkt->pts, pkt->dts, > -c->pts_offset); > +c->pts_offset, c->first_pts, > c->play_state.is_seeking); > > return 0; > > discard: > av_log(s, AV_LOG_VERBOSE, "Discarding packet @ st=%d pts=%" PRId64 " > dts=%" PRId64 " " > - "st_matched=%d\n", > + "st_matched=%d is_seeking=%d\n", >st_matched ? pkt->stream_index : -1, pkt->pts, > pkt->dts, > - st_matched); > + st_matched, c->play_state.is_seeking); > > return FFERROR_REDO; > } > @@ -1690,6 +1694,72 @@ static int dvdvideo_close(AVFormatContext *s) > return 0; > } > > +static int dvdvideo_read_seek(AVFormatContext *s, int stream_index, int64_t > timestamp, int flags) > +{ > +DVDVideoDemuxContext *c = s->priv_data; > +int ret; > +int64_t new_nav_pts; > +pci_t* new_nav_pci; > +dsi_t* new_nav_dsi; > + > +if (c->opt_menu || c->opt_chapter_start > 1) { > +av_log(s, AV_LOG_ERROR, "Seeking is not compatible with menus or > chapter extraction\n"); > + > +return AVERROR_PATCHWELCOME; > +} > + > +if ((flags & AVSEEK_FLAG_BYTE)) > +return AVERROR(ENOSYS); > + > +if (timestamp < 0) > +return AVERROR(EINVAL); > + > +if (!c->seek_warned) { > +av_log(s, AV_LOG_WARNING, "Seeking is inherently unreliable
Re: [FFmpeg-devel] [PATCH 2/2] avcodec: add Mediacodec audio decoders support
> On Jun 12, 2024, at 21:42, Matthieu Bouron wrote: > > --- > configure | 14 ++ > libavcodec/Makefile | 7 + > libavcodec/allcodecs.c| 7 + > libavcodec/mediacodecdec.c| 215 ++- > libavcodec/mediacodecdec_common.c | 333 +++--- > 5 files changed, 545 insertions(+), 31 deletions(-) > > diff --git a/configure b/configure > index 83284427df..d7de3b73ed 100755 > --- a/configure > +++ b/configure > @@ -3321,14 +3321,22 @@ amf_deps_any="libdl LoadLibrary" > nvenc_deps="ffnvcodec" > nvenc_deps_any="libdl LoadLibrary" > > +aac_mediacodec_decoder_deps="mediacodec" > +aac_mediacodec_decoder_select="aac_adtstoasc_bsf aac_parser" > aac_mf_encoder_deps="mediafoundation" > ac3_mf_encoder_deps="mediafoundation" > +amrnb_mediacodec_decoder_deps="mediacodec" > +amrnb_mediacodec_decoder_select="amr_parser" > +amrwb_mediacodec_decoder_deps="mediacodec" > +amrwb_mediacodec_decoder_select="amr_parser" > av1_cuvid_decoder_deps="cuvid CUVIDAV1PICPARAMS" > av1_mediacodec_decoder_deps="mediacodec" > av1_mediacodec_encoder_deps="mediacodec" > av1_mediacodec_encoder_select="extract_extradata_bsf" > av1_nvenc_encoder_deps="nvenc NV_ENC_PIC_PARAMS_AV1" > av1_nvenc_encoder_select="atsc_a53" > +flac_mediacodec_decoder_deps="mediacodec" > +flac_mediacodec_decoder_select="flac_parser" > h263_v4l2m2m_decoder_deps="v4l2_m2m h263_v4l2_m2m" > h263_v4l2m2m_encoder_deps="v4l2_m2m h263_v4l2_m2m" > h264_amf_encoder_deps="amf" > @@ -3377,6 +3385,8 @@ mjpeg_qsv_encoder_select="qsvenc" > mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG" > mjpeg_vaapi_encoder_select="cbs_jpeg jpegtables vaapi_encode" > mp3_mf_encoder_deps="mediafoundation" > +mp3_mediacodec_decoder_deps="mediacodec" > +mp3_mediacodec_decoder_select="mpegaudioheader" > mpeg1_cuvid_decoder_deps="cuvid" > mpeg1_v4l2m2m_decoder_deps="v4l2_m2m mpeg1_v4l2_m2m" > mpeg2_cuvid_decoder_deps="cuvid" > @@ -3394,10 +3404,14 @@ mpeg4_mmal_decoder_deps="mmal" > mpeg4_omx_encoder_deps="omx" > mpeg4_v4l2m2m_decoder_deps="v4l2_m2m mpeg4_v4l2_m2m" > mpeg4_v4l2m2m_encoder_deps="v4l2_m2m mpeg4_v4l2_m2m" > +opus_mediacodec_decoder_deps="mediacodec" > +opus_mediacodec_decoder_select="opus_parser" > vc1_cuvid_decoder_deps="cuvid" > vc1_mmal_decoder_deps="mmal" > vc1_qsv_decoder_select="qsvdec" > vc1_v4l2m2m_decoder_deps="v4l2_m2m vc1_v4l2_m2m" > +vorbis_mediacodec_decoder_deps="mediacodec" > +vorbis_mediacodec_decoder_select="vorbis_parser" > vp8_cuvid_decoder_deps="cuvid" > vp8_mediacodec_decoder_deps="mediacodec" > vp8_mediacodec_encoder_deps="mediacodec" > diff --git a/libavcodec/Makefile b/libavcodec/Makefile > index 1a44352906..64771b9944 100644 > --- a/libavcodec/Makefile > +++ b/libavcodec/Makefile > @@ -196,6 +196,7 @@ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o > aaccoder.o aacenctab.o\ > aacenc_pred.o \ > psymodel.o kbdwin.o \ > mpeg4audio_sample_rates.o > +OBJS-$(CONFIG_AAC_MEDIACODEC_DECODER) += mediacodecdec.o > OBJS-$(CONFIG_AAC_MF_ENCODER) += mfenc.o mf_utils.o > OBJS-$(CONFIG_AASC_DECODER)+= aasc.o msrledec.o > OBJS-$(CONFIG_AC3_DECODER) += ac3dec_float.o ac3dec_data.o ac3.o \ > @@ -222,6 +223,8 @@ OBJS-$(CONFIG_AMRWB_DECODER) += amrwbdec.o > celp_filters.o \ > celp_math.o acelp_filters.o \ > acelp_vectors.o \ > acelp_pitch_delay.o > +OBJS-$(CONFIG_AMRNB_MEDIACODEC_DECODER) += mediacodecdec.o > +OBJS-$(CONFIG_AMRWB_MEDIACODEC_DECODER) += mediacodecdec.o > OBJS-$(CONFIG_AMV_ENCODER) += mjpegenc.o mjpegenc_common.o > OBJS-$(CONFIG_ANM_DECODER) += anm.o > OBJS-$(CONFIG_ANULL_DECODER) += null.o > @@ -367,6 +370,7 @@ OBJS-$(CONFIG_FIC_DECODER) += fic.o > OBJS-$(CONFIG_FITS_DECODER)+= fitsdec.o fits.o > OBJS-$(CONFIG_FITS_ENCODER)+= fitsenc.o > OBJS-$(CONFIG_FLAC_DECODER)+= flacdec.o flacdata.o flacdsp.o > flac.o > +OBJS-$(CONFIG_FLAC_MEDIACODEC_DECODER) += mediacodecdec.o > OBJS-$(CONFIG_FLAC_ENCODER)+= flacenc.o flacdata.o flacencdsp.o > OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o > OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o > @@ -518,6 +522,7 @@ OBJS-$(CONFIG_MP2FIXED_ENCODER)+= > mpegaudioenc_fixed.o mpegaudio.o \ > mpegaudiotabs.o > OBJS-$(CONFIG_MP2FLOAT_DECODER)+= mpegaudiodec_float.o > OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec_fixed.o > +OBJS-$(CONFIG_MP3_MEDIACODEC_DECODER) += mediacodecdec.o > OBJS-$(CONFIG_MP3_MF_ENCODER) += mfenc.o mf_utils.o > OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec_fixed.o > OBJS-$(CONFIG_MP3ADUFLOAT_DECODER) += mpegaudiodec
Re: [FFmpeg-devel] [PATCH 2/7] avformat/dvdvideodec: Implement seeking
Hi Sean_McG, good day, First of all, there is a typo in the commit message. It should say "at the mercy of dvdnav_time_search()" > I think avpriv_report_missing_feature() might be more appropriate here. But there is no missing feature, the implementation is working great with dvdnav_time_search(). However, dvdnav_jump_to_sector_by_time() is slightly more reliable than dvdnav_time_search(). Currently, VLC player, my reference for DVD at this time, is using dvdnav_jump_to_sector_by_time() via a workaround that I am not willing to bring to FFmpeg: https://code.videolan.org/videolan/vlc/-/blob/master/modules/access/dvdnav.c#L60 The point of this "PATCHWELCOME" is to say swap to dvdnav_jump_to_sector_by_time(), when or if libdvdnav is eventually released again. > Also, does this build properly if a user does not have libdvdnav? Since the demuxer was already introduced in march and relies on dvdnav, dvdnav is a dependency. The demuxer will not be included in the build at all if the build is not configured with dvdnav and dvdread. This is the case and is documented sinc March 2024, and has not changed. Thank you! ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 1/7] avformat/dvdvideodec: Fix racy PTS calculation and frame drops
I have found a whitespace error here and need to restore 2 lines of logic, but will wait a few days for comment before putting up v2. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avcodec/aacenc: Correct option description for aac_coder fast
Ping, thank you ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 2/2] lavc/d3d12va_encode: trim header alignment at output
On 28/07/2024 15:06, Tong Wu wrote: Tong Wu: Subject: [FFmpeg-devel][PATCH 2/2] lavc/d3d12va_encode: trim header alignment at output It is d3d12va's requirement that the FrameStartOffset must be aligned as per hardware limitation. However, we could trim this alignment at output to reduce coded size. A aligned_header_size is added to D3D12VAEncodePicture. Signed-off-by: Tong Wu --- libavcodec/d3d12va_encode.c | 18 -- libavcodec/d3d12va_encode.h | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/libavcodec/d3d12va_encode.c b/libavcodec/d3d12va_encode.c index 9f7a42911e..9ee9da41e3 100644 --- a/libavcodec/d3d12va_encode.c +++ b/libavcodec/d3d12va_encode.c @@ -308,9 +308,9 @@ static int d3d12va_encode_issue(AVCodecContext *avctx, } pic->header_size = (int)bit_len / 8; -pic->header_size = pic->header_size % ctx- req.CompressedBitstreamBufferAccessAlignment ? - FFALIGN(pic->header_size, ctx- req.CompressedBitstreamBufferAccessAlignment) : - pic->header_size; +pic->aligned_header_size = pic->header_size % ctx- req.CompressedBitstreamBufferAccessAlignment ? + FFALIGN(pic->header_size, ctx- req.CompressedBitstreamBufferAccessAlignment) : + pic->header_size; hr = ID3D12Resource_Map(pic->output_buffer, 0, NULL, (void **)&ptr); if (FAILED(hr)) { @@ -318,7 +318,7 @@ static int d3d12va_encode_issue(AVCodecContext *avctx, goto fail; } -memcpy(ptr, data, pic->header_size); +memcpy(ptr, data, pic->aligned_header_size); ID3D12Resource_Unmap(pic->output_buffer, 0, NULL); } @@ -344,10 +344,10 @@ static int d3d12va_encode_issue(AVCodecContext *avctx, input_args.PictureControlDesc.PictureControlCodecData = pic->pic_ctl; input_args.PictureControlDesc.ReferenceFrames = d3d12_refs; -input_args.CurrentFrameBitstreamMetadataSize = pic->header_size; +input_args.CurrentFrameBitstreamMetadataSize = pic- aligned_header_size; output_args.Bitstream.pBuffer= pic->output_buffer; -output_args.Bitstream.FrameStartOffset = pic->header_size; +output_args.Bitstream.FrameStartOffset = pic- aligned_header_size; output_args.ReconstructedPicture.pReconstructedPicture = pic- recon_surface->texture; output_args.ReconstructedPicture.ReconstructedPictureSubresource = 0; output_args.EncoderOutputMetadata.pBuffer= pic- encoded_metadata; @@ -663,6 +663,12 @@ static int d3d12va_encode_get_coded_data(AVCodecContext *avctx, goto end; ptr = pkt->data; +memcpy(ptr, mapped_data, pic->header_size); + +ptr += pic->header_size; +mapped_data += pic->aligned_header_size; +total_size -= pic->header_size; + memcpy(ptr, mapped_data, total_size); ID3D12Resource_Unmap(pic->output_buffer, 0, NULL); diff --git a/libavcodec/d3d12va_encode.h b/libavcodec/d3d12va_encode.h index 1a0abc5bd0..51440428e4 100644 --- a/libavcodec/d3d12va_encode.h +++ b/libavcodec/d3d12va_encode.h @@ -43,6 +43,7 @@ typedef struct D3D12VAEncodePicture { FFHWBaseEncodePicture base; int header_size; +int aligned_header_size; AVD3D12VAFrame *input_surface; AVD3D12VAFrame *recon_surface; -- 2.45.1.windows.1 The first patch in this patchset has been merged earlier. Will merge this patch if there's no more comment. -Tong ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". Somehow I missed that patch. You should've ping me when I pushed the first one. Pushed. In Vulkan, we expose the raw packet we've just encoded by wrapping it as an AVBufferRef, you should consider doing this. OpenPGP_0xA2FEA5F03F034464.asc Description: OpenPGP public key OpenPGP_signature.asc Description: OpenPGP digital signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 1/2 v2] avformat/avisynth: remove atexit() handler
On 7/28/24 9:38 AM, Ramiro Polla wrote: @@ -1134,6 +1089,7 @@ static av_cold int avisynth_read_close(AVFormatContext *s) return AVERROR_UNKNOWN; avisynth_context_destroy(s->priv_data); +dlclose(avs_library.library); Maybe it's best to wrap this around an if (avs_library.library). True. I had tried toying around with C11 _Thread_local since we now use C17 as the default std, and in that case there was what I presume was a double free happening that required adding a check for whether avs_library.library still existed. As that hadn't been happening prior to that test I didn't really think much of it, but yeah, it would make sense to check it anyway. I abandoned that general idea after 1) finding out that while GCC and Clang are fine, MSVC doesn't seem to yet (or if it does, only the most recent versions of MSVC 2022 do) 2) C23 renamed it to thread_local, and most importantly, 3) I probably hadn't quite used it entirely correctly, because while the script could be parsed and played back just fine, trying to encode anything from it would segfault. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 1/1] lavfi/vf_gopromax_opencl: add GoPor Max 360 video filter
On 2024/07/28 18:26, Michael Niedermayer wrote: On Sun, Jul 28, 2024 at 01:42:09AM +0900, TADANO Tokumei wrote: On 2024/07/27 13:30, TADANO Tokumei wrote: Add an OpenCL filter for filtering GoPro Max native .360 files into standard equirectangular or youtube equiangular cubemap (eac) projection. The .360 file contains separated two video streams. This filter combine two streams into single stream with standard format. --- doc/filters.texi | 78 +++ libavfilter/Makefile | 2 + libavfilter/allfilters.c | 1 + libavfilter/opencl/gopromax.cl | 280 libavfilter/opencl_source.h | 1 + libavfilter/vf_gopromax_opencl.c | 351 +++ 6 files changed, 713 insertions(+) create mode 100644 libavfilter/opencl/gopromax.cl create mode 100644 libavfilter/vf_gopromax_opencl.c The patchwork failed, but it was caused by opencl.c (not by this patch): In file included from ./libavutil/common.h:48:0, from ./libavutil/avutil.h:301, from ./libavutil/opt.h:31, from libavdevice/sdl2.c:31: ./config.h:335:0: warning: 'HAVE_PTHREAD_SETNAME_NP' redefined #define HAVE_PTHREAD_SETNAME_NP 0 In file included from /usr/include/SDL2/SDL_stdinc.h:31:0, from /usr/include/SDL2/SDL_main.h:25, from /usr/include/SDL2/SDL.h:32, from libavdevice/sdl2.c:26: /usr/include/SDL2/SDL_config.h:186:0: note: this is the location of the previous definition #define HAVE_PTHREAD_SETNAME_NP 1 In file included from libavfilter/opencl.h:31:0, from libavfilter/opencl.c:26: ./libavutil/hwcontext_opencl.h:25:10: fatal error: CL/cl.h: No such file or directory #include ^ compilation terminated. make: *** [libavfilter/opencl.o] Error 1 with this patch it fails here on ubuntu: /usr/bin/ld: libavfilter/libavfilter.a(opencl.o): undefined reference to symbol 'clBuildProgram@@OPENCL_1.0' /usr/bin/ld: /usr/local/cuda/targets/x86_64-linux/lib/libOpenCL.so.1: error adding symbols: DSO missing from command line thx I tested on Ubuntu 22.04, and it works fine. As message shows, it seems the error is not related to this patch but OpenCL library. [...] ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] lavu/riscv: Revert d808070, removing AV_READ_TIME
The implementation of ff_read_time() for RISC-V uses rdtime which has precision on existing hardware too low (!) for benchmarking purposes. Deleting this implementation falls back on clock_gettime() which was added as the default ff_read_time() implementation in 33e4cc9. Below are metrics gathered on SpacemiT K1, before and after this commit: Before: $ tests/checkasm/checkasm --bench benchmarking with native FFmpeg timers nop: 0.0 checkasm: using random seed 3473665261 checkasm: bench runs 1024 (1 << 10) RVI: - pixblockdsp.get_pixels[OK] - vc1dsp.mspel_pixels [OK] RVF: - audiodsp.audiodsp [OK] checkasm: all 4 tests passed audiodsp.vector_clipf_c: 1388.7 audiodsp.vector_clipf_rvf: 261.5 get_pixels_c: 2.0 get_pixels_rvi: 1.5 vc1dsp.put_vc1_mspel_pixels_tab[0][0]_c: 8.0 vc1dsp.put_vc1_mspel_pixels_tab[0][0]_rvi: 1.0 vc1dsp.put_vc1_mspel_pixels_tab[1][0]_c: 2.0 vc1dsp.put_vc1_mspel_pixels_tab[1][0]_rvi: 0.5 After: $ tests/checkasm/checkasm --bench benchmarking with native FFmpeg timers nop: 56.4 checkasm: using random seed 1021411603 checkasm: bench runs 1024 (1 << 10) RVI: - pixblockdsp.get_pixels[OK] - vc1dsp.mspel_pixels [OK] RVF: - audiodsp.audiodsp [OK] checkasm: all 4 tests passed audiodsp.vector_clipf_c: 23236.4 audiodsp.vector_clipf_rvf: 11038.4 get_pixels_c: 79.6 get_pixels_rvi: 48.4 vc1dsp.put_vc1_mspel_pixels_tab[0][0]_c: 329.6 vc1dsp.put_vc1_mspel_pixels_tab[0][0]_rvi: 38.1 vc1dsp.put_vc1_mspel_pixels_tab[1][0]_c: 89.9 vc1dsp.put_vc1_mspel_pixels_tab[1][0]_rvi: 17.1 --- libavutil/riscv/timer.h | 54 - libavutil/timer.h | 2 -- 2 files changed, 56 deletions(-) delete mode 100644 libavutil/riscv/timer.h diff --git a/libavutil/riscv/timer.h b/libavutil/riscv/timer.h deleted file mode 100644 index 174b469cbe..00 --- a/libavutil/riscv/timer.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_RISCV_TIMER_H -#define AVUTIL_RISCV_TIMER_H - -#include "config.h" - -#if HAVE_INLINE_ASM -#include - -static inline uint64_t ff_read_time(void) -{ -#if (__riscv_xlen >= 64) -uintptr_t cycles; - -__asm__ volatile ("rdtime %0" : "=r" (cycles)); - -#else -uint64_t cycles; -uint32_t hi, lo, check; - -__asm__ volatile ( -"1: rdtimeh %0\n" -" rdtime %1\n" -" rdtimeh %2\n" -" bne %0, %2, 1b\n" : "=r" (hi), "=r" (lo), "=r" (check)); - -cycles = (((uint64_t)hi) << 32) | lo; - -#endif -return cycles; -} - -#define AV_READ_TIME ff_read_time -#define FF_TIMER_UNITS "ticks" - -#endif -#endif /* AVUTIL_RISCV_TIMER_H */ diff --git a/libavutil/timer.h b/libavutil/timer.h index 9fe6aa1385..663daf81c6 100644 --- a/libavutil/timer.h +++ b/libavutil/timer.h @@ -61,8 +61,6 @@ # include "arm/timer.h" #elif ARCH_PPC # include "ppc/timer.h" -#elif ARCH_RISCV -# include "riscv/timer.h" #elif ARCH_X86 # include "x86/timer.h" #elif ARCH_LOONGARCH -- 2.45.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] lavc/bswapdsp: add RV Zvbb bswap16 and bswap32
--- libavcodec/riscv/Makefile| 1 + libavcodec/riscv/bswapdsp_init.c | 11 ++- libavcodec/riscv/bswapdsp_rvvb.S | 52 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 libavcodec/riscv/bswapdsp_rvvb.S diff --git a/libavcodec/riscv/Makefile b/libavcodec/riscv/Makefile index 0bbdd38116..8195c7a388 100644 --- a/libavcodec/riscv/Makefile +++ b/libavcodec/riscv/Makefile @@ -16,6 +16,7 @@ RVV-OBJS-$(CONFIG_BLOCKDSP) += riscv/blockdsp_rvv.o OBJS-$(CONFIG_BSWAPDSP) += riscv/bswapdsp_init.o RV-OBJS-$(CONFIG_BSWAPDSP) += riscv/bswapdsp_rvb.o RVV-OBJS-$(CONFIG_BSWAPDSP) += riscv/bswapdsp_rvv.o +RVVB-OBJS-$(CONFIG_BSWAPDSP) += riscv/bswapdsp_rvvb.o OBJS-$(CONFIG_EXR_DECODER) += riscv/exrdsp_init.o RVV-OBJS-$(CONFIG_EXR_DECODER) += riscv/exrdsp_rvv.o OBJS-$(CONFIG_FLAC_DECODER) += riscv/flacdsp_init.o diff --git a/libavcodec/riscv/bswapdsp_init.c b/libavcodec/riscv/bswapdsp_init.c index d490c434e7..ce36d419d2 100644 --- a/libavcodec/riscv/bswapdsp_init.c +++ b/libavcodec/riscv/bswapdsp_init.c @@ -27,6 +27,8 @@ void ff_bswap32_buf_rvb(uint32_t *dst, const uint32_t *src, int len); void ff_bswap16_buf_rvv(uint16_t *dst, const uint16_t *src, int len); +void ff_bswap32_buf_rvvb(uint32_t *dst, const uint32_t *src, int len); +void ff_bswap16_buf_rvvb(uint16_t *dst, const uint16_t *src, int len); av_cold void ff_bswapdsp_init_riscv(BswapDSPContext *c) { @@ -39,8 +41,15 @@ av_cold void ff_bswapdsp_init_riscv(BswapDSPContext *c) c->bswap_buf = ff_bswap32_buf_rvb; #endif #if HAVE_RVV -if (flags & AV_CPU_FLAG_RVV_I32) +if (flags & AV_CPU_FLAG_RVV_I32) { c->bswap16_buf = ff_bswap16_buf_rvv; +# if HAVE_RV_ZVBB +if (flags & AV_CPU_FLAG_RV_ZVBB) { +c->bswap_buf = ff_bswap32_buf_rvvb; +c->bswap16_buf = ff_bswap16_buf_rvvb; +} +# endif +} #endif } #endif diff --git a/libavcodec/riscv/bswapdsp_rvvb.S b/libavcodec/riscv/bswapdsp_rvvb.S new file mode 100644 index 00..165ac104a9 --- /dev/null +++ b/libavcodec/riscv/bswapdsp_rvvb.S @@ -0,0 +1,52 @@ +/* + * Copyright © 2024 Rémi Denis-Courmont. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/riscv/asm.S" + +func ff_bswap32_buf_rvvb, zve32x, zvbb, zba +lpad0 +1: +vsetvli t0, a2, e32, m8, ta, ma +vle32.v v8, (a1) +sub a2, a2, t0 +vrev8.v v8, v8 +sh2add a1, t0, a1 +vse32.v v8, (a0) +sh2add a0, t0, a0 +bneza2, 1b + +ret +endfunc + +func ff_bswap16_buf_rvvb, zve32x, zvbb, zba +lpad0 +1: +vsetvli t0, a2, e16, m8, ta, ma +vle16.v v8, (a1) +sub a2, a2, t0 +vrev8.v v8, v8 +sh1add a1, t0, a1 +vse16.v v8, (a0) +sh1add a0, t0, a0 +bneza2, 1b + +ret +endfunc -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] lavc/rv34dsp: use saturating add/sub for R-V V DC add
T-Head C908 (cycles): rv34_idct_dc_add_c: 113.2 rv34_idct_dc_add_rvv_i32: 48.5 (before) rv34_idct_dc_add_rvv_i32: 39.5 (after) --- libavcodec/riscv/rv34dsp_rvv.S | 19 +++ 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/libavcodec/riscv/rv34dsp_rvv.S b/libavcodec/riscv/rv34dsp_rvv.S index 98871507c2..70c88fdca5 100644 --- a/libavcodec/riscv/rv34dsp_rvv.S +++ b/libavcodec/riscv/rv34dsp_rvv.S @@ -42,14 +42,17 @@ func ff_rv34_idct_dc_add_rvv, zve32x mul t1, t1, a2 addi t1, t1, 512 srai t1, t1, 10 -vsetivli zero, 4*4, e16, m2, ta, ma -vzext.vf2 v2, v0 -vadd.vx v2, v2, t1 -vmax.vx v2, v2, zero -vsetvli zero, zero, e8, m1, ta, ma -vnclipu.wiv0, v2, 0 -vsetivli zero, 4, e8, mf4, ta, ma -vsse32.v v0, (a0), a1 +vsetivlizero, 4*4, e8, m2, ta, ma +bgezt1, 1f +neg t1, t1 +vssubu.vx v0, v0, t1 +vsetivlizero, 4, e8, mf4, ta, ma +vsse32.vv0, (a0), a1 +ret +1: +vsaddu.vx v0, v0, t1 +vsetivlizero, 4, e8, mf4, ta, ma +vsse32.vv0, (a0), a1 ret endfunc -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 1/2] avcodec/pngdec: use 8-bit sBIT cap for indexed PNGs per spec
On 7/19/24 12:04 PM, Leo Izen wrote: The PNG specification[1] says that sBIT entries must be at most the bit depth specified in IHDR, unless the PNG is indexed-color, in which case sBIT must be between 1 and 8. We should not reject valid sBITs on PNGs with indexed color. [1]: https://www.w3.org/TR/png-3/#11sBIT Regression since 84b454935fae2633a8a5dd075e22393f3e8f932f. Signed-off-by: Leo Izen Reported-by: Ramiro Polla --- Will merge soon. - Leo Izen (Traneptora) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/2] avformat/mov: Avoid overflow in dts
This basically ignores the overflow without undefined behavior, alternatively we could detect and error out Fixes: signed integer overflow: 6310596683470275584 + 7660622966157213696 cannot be represented in type 'long' Fixes: 70433/clusterfuzz-testcase-minimized-ffmpeg_IO_DEMUXER_fuzzer-5483347233538048 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavformat/mov.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index b74e43e2140..403af1bba17 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -3472,10 +3472,10 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) sc->stts_data[i].duration = 1; corrected_dts += (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count; } else { -corrected_dts += sample_duration * (int64_t)sample_count; +corrected_dts += sample_duration * (uint64_t)sample_count; } -current_dts += sc->stts_data[i].duration * (int64_t)sample_count; +current_dts += sc->stts_data[i].duration * (uint64_t)sample_count; if (current_dts > corrected_dts) { int64_t drift = (current_dts - corrected_dts)/FFMAX(sample_count, 1); -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/2] avformat/matroskadec: Check desc_bytes so bits fit in 64bit
Likely a tighter check can be done Fixes: signed integer overflow: 3305606804154370442 * 8 cannot be represented in type 'long' Fixes: 70449/clusterfuzz-testcase-minimized-ffmpeg_dem_WEBM_DASH_MANIFEST_fuzzer-4771166007918592 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavformat/matroskadec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index aa28a37da4c..175d6a3ef61 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -4633,7 +4633,7 @@ static int64_t webm_dash_manifest_compute_bandwidth(AVFormatContext *s, int64_t int64_t desc_bytes = desc_end.end_offset - desc_beg.start_offset; int64_t desc_ns = desc_end.end_time_ns - desc_beg.start_time_ns; double desc_sec, calc_bits_per_second, percent, mod_bits_per_second; -if (desc_bytes <= 0) +if (desc_bytes <= 0 || desc_bytes > INT64_MAX/8) return -1; desc_sec = desc_ns / nano_seconds_per_second; -- 2.45.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 1/1] lavfi/vf_gopromax_opencl: add GoPor Max 360 video filter
On 2024/07/29 1:30, TADANO Tokumei wrote: On 2024/07/28 18:26, Michael Niedermayer wrote: On Sun, Jul 28, 2024 at 01:42:09AM +0900, TADANO Tokumei wrote: On 2024/07/27 13:30, TADANO Tokumei wrote: Add an OpenCL filter for filtering GoPro Max native .360 files into standard equirectangular or youtube equiangular cubemap (eac) projection. The .360 file contains separated two video streams. This filter combine two streams into single stream with standard format. --- doc/filters.texi | 78 +++ libavfilter/Makefile | 2 + libavfilter/allfilters.c | 1 + libavfilter/opencl/gopromax.cl | 280 libavfilter/opencl_source.h | 1 + libavfilter/vf_gopromax_opencl.c | 351 +++ 6 files changed, 713 insertions(+) create mode 100644 libavfilter/opencl/gopromax.cl create mode 100644 libavfilter/vf_gopromax_opencl.c The patchwork failed, but it was caused by opencl.c (not by this patch): In file included from ./libavutil/common.h:48:0, from ./libavutil/avutil.h:301, from ./libavutil/opt.h:31, from libavdevice/sdl2.c:31: ./config.h:335:0: warning: 'HAVE_PTHREAD_SETNAME_NP' redefined #define HAVE_PTHREAD_SETNAME_NP 0 In file included from /usr/include/SDL2/SDL_stdinc.h:31:0, from /usr/include/SDL2/SDL_main.h:25, from /usr/include/SDL2/SDL.h:32, from libavdevice/sdl2.c:26: /usr/include/SDL2/SDL_config.h:186:0: note: this is the location of the previous definition #define HAVE_PTHREAD_SETNAME_NP 1 In file included from libavfilter/opencl.h:31:0, from libavfilter/opencl.c:26: ./libavutil/hwcontext_opencl.h:25:10: fatal error: CL/cl.h: No such file or directory #include ^ compilation terminated. make: *** [libavfilter/opencl.o] Error 1 with this patch it fails here on ubuntu: /usr/bin/ld: libavfilter/libavfilter.a(opencl.o): undefined reference to symbol 'clBuildProgram@@OPENCL_1.0' /usr/bin/ld: /usr/local/cuda/targets/x86_64-linux/lib/libOpenCL.so.1: error adding symbols: DSO missing from command line thx I tested on Ubuntu 22.04, and it works fine. As message shows, it seems the error is not related to this patch but OpenCL library. I found I have to add `gopromax_opencl_filter_deps="opencl"` in configure file. I'll amend the patch later. [...] ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avcodec/aacenc: Correct option description for aac_coder fast
On 7/14/24 1:00 AM, Marth64 wrote: The description advertises fast as "Default fast search", but this has not been the default for a long time (current default is twoloop). Signed-off-by: Marth64 --- libavcodec/aacenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index 163598e938..88037c7f87 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -1392,7 +1392,7 @@ static const AVOption aacenc_options[] = { {"aac_coder", "Coding algorithm", offsetof(AACEncContext, options.coder), AV_OPT_TYPE_INT, {.i64 = AAC_CODER_TWOLOOP}, 0, AAC_CODER_NB-1, AACENC_FLAGS, .unit = "coder"}, {"anmr", "ANMR method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_ANMR},INT_MIN, INT_MAX, AACENC_FLAGS, .unit = "coder"}, {"twoloop", "Two loop searching method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_TWOLOOP}, INT_MIN, INT_MAX, AACENC_FLAGS, .unit = "coder"}, -{"fast", "Default fast search", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_FAST},INT_MIN, INT_MAX, AACENC_FLAGS, .unit = "coder"}, +{"fast", "Fast search", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_FAST},INT_MIN, INT_MAX, AACENC_FLAGS, .unit = "coder"}, {"aac_ms", "Force M/S stereo coding", offsetof(AACEncContext, options.mid_side), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AACENC_FLAGS}, {"aac_is", "Intensity stereo coding", offsetof(AACEncContext, options.intensity_stereo), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS}, {"aac_pns", "Perceptual noise substitution", offsetof(AACEncContext, options.pns), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS}, This LGTM, I will apply it soon. - Leo Izen (Traneptora) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v4 1/2] libavformat/vapoursynth: Update to API version 4, load library at runtime
Am 28.07.24 um 15:09 schrieb Ramiro Polla: if (st->codecpar->format == AV_PIX_FMT_NONE) { - av_log(s, AV_LOG_ERROR, "Unsupported VS pixel format %s\n", info->format->name); + if(vs->vsapi->getVideoFormatName(&info->format, vsfmt)) + av_log(s, AV_LOG_ERROR, "Unsupported VS pixel format %s\n", vsfmt); + else + av_log(s, AV_LOG_ERROR, "Unsupported VS pixel format\n"); err = AVERROR_EXTERNAL; goto done; } - av_log(s, AV_LOG_VERBOSE, "VS format %s -> pixfmt %s\n", info->format->name, - av_get_pix_fmt_name(st->codecpar->format)); - - if (info->format->colorFamily == cmYCoCg) - st->codecpar->color_space = AVCOL_SPC_YCGCO; + if (vs->vsapi->getVideoFormatName(&info->format, vsfmt)) + av_log(s, AV_LOG_VERBOSE, "VS format %s -> pixfmt %s\n", + vsfmt, av_get_pix_fmt_name(st->codecpar->format)); + else + av_log(s, AV_LOG_VERBOSE, "VS format -> pixfmt %s\n", + av_get_pix_fmt_name(st->codecpar->format)); Could you change this to have a single call go av_log()? Possibly using a %s with a string for the unknown format. Same thing for the other av_log() above. [...] It now prints "(unknown)" for a video format that VapourSynth cannot resolve. "(unknown)" is also printed at other places in ffmpeg in similar cases, so it's consistent. Also could you give us a very minimal test script to test this? I have attached a minimal test script, it will generate 10 frames each black, red, green, blue in 640x480, RGB24 Best regards Stefan From 2279d2e225c665cab68d26652e1cca4fdf04faaa Mon Sep 17 00:00:00 2001 From: Stefan Oltmanns Date: Mon, 29 Jul 2024 05:08:57 +0200 Subject: [PATCH 1/2] avformat/vapoursynth: Update to API version 4 Signed-off-by: Stefan Oltmanns --- configure | 2 +- libavformat/vapoursynth.c | 77 --- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/configure b/configure index f6f5c29fea..c50b5ad4b4 100755 --- a/configure +++ b/configure @@ -7085,7 +7085,7 @@ enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/r { enabled libdrm || die "ERROR: rkmpp requires --enable-libdrm"; } } -enabled vapoursynth && require_pkg_config vapoursynth "vapoursynth-script >= 42" VSScript.h vsscript_init +enabled vapoursynth && require_pkg_config vapoursynth "vapoursynth-script >= 55" VSScript4.h getVSScriptAPI if enabled gcrypt; then diff --git a/libavformat/vapoursynth.c b/libavformat/vapoursynth.c index 8a2519e19a..26c9986138 100644 --- a/libavformat/vapoursynth.c +++ b/libavformat/vapoursynth.c @@ -25,8 +25,7 @@ #include -#include -#include +#include #include "libavutil/avassert.h" #include "libavutil/avstring.h" @@ -41,6 +40,7 @@ #include "internal.h" struct VSState { +const VSSCRIPTAPI *vssapi; VSScript *vss; }; @@ -49,10 +49,10 @@ typedef struct VSContext { AVBufferRef *vss_state; +const VSSCRIPTAPI *vssapi; const VSAPI *vsapi; -VSCore *vscore; -VSNodeRef *outnode; +VSNode *outnode; int is_cfr; int current_frame; @@ -75,8 +75,7 @@ static void free_vss_state(void *opaque, uint8_t *data) struct VSState *vss = opaque; if (vss->vss) { -vsscript_freeScript(vss->vss); -vsscript_finalize(); +vss->vssapi->freeScript(vss->vss); } } @@ -90,7 +89,6 @@ static av_cold int read_close_vs(AVFormatContext *s) av_buffer_unref(&vs->vss_state); vs->vsapi = NULL; -vs->vscore = NULL; vs->outnode = NULL; return 0; @@ -106,7 +104,7 @@ static av_cold int is_native_endian(enum AVPixelFormat pixfmt) return pd && (!!HAVE_BIGENDIAN == !!(pd->flags & AV_PIX_FMT_FLAG_BE)); } -static av_cold enum AVPixelFormat match_pixfmt(const VSFormat *vsf, int c_order[4]) +static av_cold enum AVPixelFormat match_pixfmt(const VSVideoFormat *vsf, int c_order[4]) { static const int yuv_order[4] = {0, 1, 2, 0}; static const int rgb_order[4] = {1, 2, 0, 0}; @@ -128,13 +126,12 @@ static av_cold enum AVPixelFormat match_pixfmt(const VSFormat *vsf, int c_order[ pd->log2_chroma_h != vsf->subSamplingH) continue; -is_rgb = vsf->colorFamily == cmRGB; +is_rgb = vsf->colorFamily == cfRGB; if (is_rgb != !!(pd->flags & AV_PIX_FMT_FLAG_RGB)) continue; -is_yuv = vsf->colorFamily == cmYUV || - vsf->colorFamily == cmYCoCg || - vsf->colorFamily == cmGray; +is_yuv = vsf->colorFamily == cfYUV || + vsf->colorFamily == cfGray; if (!is_rgb && !is_yuv) continue; @@ -176,15 +173,30 @@ static av_cold int read_header_vs(AVFormatContext *s) int64_t sz = avio_size(pb); char *buf = NULL; char dummy; +char vsfmt[3
Re: [FFmpeg-devel] [PATCH v3 2/2] libavformat/vapoursynth: Update to API version 4, load library at runtime
Am 28.07.24 um 15:15 schrieb Ramiro Polla: + void *vslibrary = NULL; +#ifdef _WIN32 + const HKEY hkeys[] = {HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE}; + LONG r; + WCHAR vss_path[512]; + DWORD buf_size = sizeof(vss_path) - 2; + char *vss_path_utf8; + int i; + + for (i = 0; i < sizeof(hkeys); i++) { FF_ARRAY_ELEMS(hkeys) fixed + if ((r = RegGetValueW(hkeys[i], L"SOFTWARE\\VapourSynth", + L"VSScriptDLL", RRF_RT_REG_SZ, NULL, + &vss_path, &buf_size)) == ERROR_SUCCESS) + break; + } + if (r == ERROR_SUCCESS && wchartoutf8(vss_path, &vss_path_utf8) == 0) { + vslibrary = dlopen(vss_path_utf8, RTLD_NOW | RTLD_GLOBAL); I think calling win32_dlopen() with a full path will be problematic for systems without KB2533623. win32_dlopen() might need to be fixed in a separate patch. Yes, win32_dlopen would need to check if a full path is already given and if yes skip all the stuff to determine it's own and system32 path, but instead just use the given parameter directly. To check if it's a full path it should be enough to check if it either starts with "\??\" (NT-style path) or if the second character is ":" (win32 style path). But is this really is needed for an operating system that reached support end over 4 years ago and does not have a security patch applied released over 13 years ago? I don't know what ffmpeg's exact policy is in this case, just asking. Best regards Stefan From dc396711d050c112b2ef6c37fdb67c4ec59c16a1 Mon Sep 17 00:00:00 2001 From: Stefan Oltmanns Date: Mon, 29 Jul 2024 05:12:31 +0200 Subject: [PATCH 2/2] avformat/vapoursynth: load library at runtime Signed-off-by: Stefan Oltmanns --- configure | 2 +- libavformat/vapoursynth.c | 65 +-- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/configure b/configure index c50b5ad4b4..1b6670505a 100755 --- a/configure +++ b/configure @@ -7085,7 +7085,7 @@ enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/r { enabled libdrm || die "ERROR: rkmpp requires --enable-libdrm"; } } -enabled vapoursynth && require_pkg_config vapoursynth "vapoursynth-script >= 55" VSScript4.h getVSScriptAPI +enabled vapoursynth && require_headers "vapoursynth/VSScript4.h vapoursynth/VapourSynth4.h" if enabled gcrypt; then diff --git a/libavformat/vapoursynth.c b/libavformat/vapoursynth.c index 26c9986138..0fa5affa63 100644 --- a/libavformat/vapoursynth.c +++ b/libavformat/vapoursynth.c @@ -25,7 +25,7 @@ #include -#include +#include #include "libavutil/avassert.h" #include "libavutil/avstring.h" @@ -39,11 +39,26 @@ #include "demux.h" #include "internal.h" +/* Platform-specific directives. */ +#ifdef _WIN32 + #include + #include "compat/w32dlfcn.h" + #include "libavutil/wchar_filename.h" + #undef EXTERN_C + #define VSSCRIPT_LIB "VSScript.dll" +#else + #include + #define VSSCRIPT_NAME "libvapoursynth-script" + #define VSSCRIPT_LIB VSSCRIPT_NAME SLIBSUF +#endif + struct VSState { const VSSCRIPTAPI *vssapi; VSScript *vss; }; +typedef const VSSCRIPTAPI *(*VSScriptGetAPIFunc)(int version); + typedef struct VSContext { const AVClass *class; @@ -51,6 +66,7 @@ typedef struct VSContext { const VSSCRIPTAPI *vssapi; const VSAPI *vsapi; +void *vslibrary; VSNode *outnode; int is_cfr; @@ -70,6 +86,40 @@ static const AVOption options[] = { {NULL} }; +static av_cold void* vs_load_library(VSScriptGetAPIFunc *get_vssapi) +{ +void *vslibrary = NULL; +#ifdef _WIN32 +const HKEY hkeys[] = {HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE}; +LONG r; +WCHAR vss_path[512]; +DWORD buf_size = sizeof(vss_path) - 2; +char *vss_path_utf8; +int i; + +for (i = 0; i < FF_ARRAY_ELEMS(hkeys); i++) { +if ((r = RegGetValueW(hkeys[i], L"SOFTWARE\\VapourSynth", + L"VSScriptDLL", RRF_RT_REG_SZ, NULL, + &vss_path, &buf_size)) == ERROR_SUCCESS) +break; +} +if (r == ERROR_SUCCESS && wchartoutf8(vss_path, &vss_path_utf8) == 0) { +vslibrary = dlopen(vss_path_utf8, RTLD_NOW | RTLD_GLOBAL); +av_free(vss_path_utf8); +} +else +#endif +vslibrary = dlopen(VSSCRIPT_LIB, RTLD_NOW | RTLD_GLOBAL); + +if (vslibrary != NULL) { +if (!(*get_vssapi = (VSScriptGetAPIFunc)dlsym(vslibrary, "getVSScriptAPI"))) { +dlclose(vslibrary); +return NULL; +} +} +return vslibrary; +} + static void free_vss_state(void *opaque, uint8_t *data) { struct VSState *vss = opaque; @@ -91,6 +141,9 @@ static av_cold int read_close_vs(AVFormatContext *s) vs->vsapi = NULL; vs->outnode = NULL; +if (vs->vslibrary) +dlclose(vs->vslibrary); + return 0; } @@ -170,6 +223,7 @
[FFmpeg-devel] [PATCH 3/4] avformat/avisynth: remove library allocation from global state
As part of this, the mutexes are no longer necessary, and avisynth_read_close needs to check that avs->avs_library.library still exists before it attempts to call avisynth_context_destroy and dlclose. Signed-off-by: Stephen Hutchinson --- libavformat/avisynth.c | 133 - 1 file changed, 64 insertions(+), 69 deletions(-) diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c index b01263e010..b91d77b8d8 100644 --- a/libavformat/avisynth.c +++ b/libavformat/avisynth.c @@ -115,6 +115,7 @@ typedef struct AviSynthContext { int error; uint32_t flags; +struct AviSynthLibrary avs_library; } AviSynthContext; static const int avs_planes_packed[1] = { 0 }; @@ -128,20 +129,16 @@ static const int avs_planes_yuva[4] = { AVS_PLANAR_Y, AVS_PLANAR_U, static const int avs_planes_rgba[4] = { AVS_PLANAR_G, AVS_PLANAR_B, AVS_PLANAR_R, AVS_PLANAR_A }; -static AVMutex avisynth_mutex = AV_MUTEX_INITIALIZER; - -static AviSynthLibrary avs_library; - -static av_cold int avisynth_load_library(void) +static av_cold int avisynth_load_library(AviSynthContext *avs) { -avs_library.library = dlopen(AVISYNTH_LIB, RTLD_NOW | RTLD_LOCAL); -if (!avs_library.library) +avs->avs_library.library = dlopen(AVISYNTH_LIB, RTLD_NOW | RTLD_LOCAL); +if (!avs->avs_library.library) return AVERROR_UNKNOWN; #define LOAD_AVS_FUNC(name, continue_on_fail) \ -avs_library.name = (name ## _func) \ - dlsym(avs_library.library, #name); \ -if (!continue_on_fail && !avs_library.name)\ +avs->avs_library.name = (name ## _func) \ + dlsym(avs->avs_library.library, #name); \ +if (!continue_on_fail && !avs->avs_library.name)\ goto fail; LOAD_AVS_FUNC(avs_bit_blt, 0); @@ -177,7 +174,7 @@ static av_cold int avisynth_load_library(void) return 0; fail: -dlclose(avs_library.library); +dlclose(avs->avs_library.library); return AVERROR_UNKNOWN; } @@ -189,13 +186,13 @@ static av_cold int avisynth_context_create(AVFormatContext *s) AviSynthContext *avs = s->priv_data; int ret; -if (!avs_library.library) -if (ret = avisynth_load_library()) +if (!avs->avs_library.library) +if (ret = avisynth_load_library(avs)) return ret; -avs->env = avs_library.avs_create_script_environment(3); -if (avs_library.avs_get_error) { -const char *error = avs_library.avs_get_error(avs->env); +avs->env = avs->avs_library.avs_create_script_environment(3); +if (avs->avs_library.avs_get_error) { +const char *error = avs->avs_library.avs_get_error(avs->env); if (error) { av_log(s, AV_LOG_ERROR, "%s\n", error); return AVERROR_UNKNOWN; @@ -208,11 +205,11 @@ static av_cold int avisynth_context_create(AVFormatContext *s) static av_cold void avisynth_context_destroy(AviSynthContext *avs) { if (avs->clip) { -avs_library.avs_release_clip(avs->clip); +avs->avs_library.avs_release_clip(avs->clip); avs->clip = NULL; } if (avs->env) { -avs_library.avs_delete_script_environment(avs->env); +avs->avs_library.avs_delete_script_environment(avs->env); avs->env = NULL; } } @@ -486,17 +483,17 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) * version 9 at the minimum. Technically, 8.1 works, but the time * distance between 8.1 and 9 is very small, so just restrict it to 9. */ -if (avs_library.avs_get_version(avs->clip) >= 9) { +if (avs->avs_library.avs_get_version(avs->clip) >= 9) { -frame = avs_library.avs_get_frame(avs->clip, 0); -avsmap = avs_library.avs_get_frame_props_ro(avs->env, frame); +frame = avs->avs_library.avs_get_frame(avs->clip, 0); +avsmap = avs->avs_library.avs_get_frame_props_ro(avs->env, frame); /* Field order */ if(avs->flags & AVISYNTH_FRAMEPROP_FIELD_ORDER) { -if(avs_library.avs_prop_get_type(avs->env, avsmap, "_FieldBased") == AVS_PROPTYPE_UNSET) { +if(avs->avs_library.avs_prop_get_type(avs->env, avsmap, "_FieldBased") == AVS_PROPTYPE_UNSET) { st->codecpar->field_order = AV_FIELD_UNKNOWN; } else { -switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_FieldBased", 0, &error)) { +switch (avs->avs_library.avs_prop_get_int(avs->env, avsmap, "_FieldBased", 0, &error)) { case 0: st->codecpar->field_order = AV_FIELD_PROGRESSIVE; break; @@ -514,10 +511,10 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) /* Color Range */
[FFmpeg-devel] [PATCH 4/4] avformat/avisynth: move avs_planes* consts into relevant function
These consts are only used in the switch(planar) case located in avisynth_create_stream_video and nowhere else in the demuxer, so move them into that function directly. Signed-off-by: Stephen Hutchinson --- libavformat/avisynth.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c index b91d77b8d8..cb2be10925 100644 --- a/libavformat/avisynth.c +++ b/libavformat/avisynth.c @@ -118,17 +118,6 @@ typedef struct AviSynthContext { struct AviSynthLibrary avs_library; } AviSynthContext; -static const int avs_planes_packed[1] = { 0 }; -static const int avs_planes_grey[1] = { AVS_PLANAR_Y }; -static const int avs_planes_yuv[3]= { AVS_PLANAR_Y, AVS_PLANAR_U, - AVS_PLANAR_V }; -static const int avs_planes_rgb[3]= { AVS_PLANAR_G, AVS_PLANAR_B, - AVS_PLANAR_R }; -static const int avs_planes_yuva[4] = { AVS_PLANAR_Y, AVS_PLANAR_U, - AVS_PLANAR_V, AVS_PLANAR_A }; -static const int avs_planes_rgba[4] = { AVS_PLANAR_G, AVS_PLANAR_B, - AVS_PLANAR_R, AVS_PLANAR_A }; - static av_cold int avisynth_load_library(AviSynthContext *avs) { avs->avs_library.library = dlopen(AVISYNTH_LIB, RTLD_NOW | RTLD_LOCAL); @@ -225,6 +214,17 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) int sar_num = 1; int sar_den = 1; +static const int avs_planes_packed[1] = { 0 }; +static const int avs_planes_grey[1] = { AVS_PLANAR_Y }; +static const int avs_planes_yuv[3]= { AVS_PLANAR_Y, AVS_PLANAR_U, + AVS_PLANAR_V }; +static const int avs_planes_rgb[3]= { AVS_PLANAR_G, AVS_PLANAR_B, + AVS_PLANAR_R }; +static const int avs_planes_yuva[4] = { AVS_PLANAR_Y, AVS_PLANAR_U, + AVS_PLANAR_V, AVS_PLANAR_A }; +static const int avs_planes_rgba[4] = { AVS_PLANAR_G, AVS_PLANAR_B, + AVS_PLANAR_R, AVS_PLANAR_A }; + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; st->codecpar->width = avs->vi->width; -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".