Re: [FFmpeg-devel] can not run encoding example of FFmpeg
Hi, The linked version is an old version of the example. Latest version is in git doc/encode_video.c. It runs ok on Mac. Can you try again with the newest version? ___ 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 00/19] swscale: major API refactor and new graph dispatch
This patch series introduces the new API that was discussed in my previous series, and starts working towards a new, graph-based scaler dispatch mechanism. This currently piggybacks off of existing swscale logic, but I plan on incrementally rewriting the high-level innards going forwards. In order te preserve backwards compatibility, and to provide a clear migration path, the old type names and API functions are still accessible, and the new implementation is hidden inside the same SwsInternal struct. This allows us to reclaim the same symbol name while only wasting around 40 kB of memory per allocated SwsContext. In the future, this will become less as the old context gets deprecated and eventually removed, in favor of less monolithic, individual filter passes. The downside of this approach is that users must explicitly choose to either use the "new" API usage style or the "old" API usage style, conditionally on whether or not sws_init_context() was called, and cannot mix and match the two. However, this should not be a major issue in practice, as the only way to use the new API is by deliberatily *omitting* all of the legacy init calls, something that legacy API users cannot possibly do. In exchange for this, we gain the massive upside of not needing to use sws_alloc_context2(), sws_scale_frame2() and so on. I consider this a decent compromise. Lastly, I also rewrote the test framework to facilitate further development of the new API, and to benchmark it to fend off any unintended performance regressions. The peformance should be pretty similar accross the board, since the implementation didn't really change so far. However, some cases have gotten dramatically faster, for example xyz12le -> yuv420p, since cascaded contexts and XYZ pre-passes can now be properly threaded. This results in an almost 400% speed improvement on my machine at 1080p. ___ 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/19] swscale: publicly typedef struct SwsContext
From: Niklas Haas Slightly more convenient, especially for the upcoming refactor which will turn SwsContext into a public struct. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/swscale.h | 36 ++-- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/libswscale/swscale.h b/libswscale/swscale.h index e575695c05..2604eb1624 100644 --- a/libswscale/swscale.h +++ b/libswscale/swscale.h @@ -150,7 +150,7 @@ typedef struct SwsFilter { SwsVector *chrV; } SwsFilter; -struct SwsContext; +typedef struct SwsContext SwsContext; /** * Return a positive value if pix_fmt is a supported input format, 0 @@ -176,7 +176,7 @@ int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt); * sws_init_context(). For filling see AVOptions, options.c and * sws_setColorspaceDetails(). */ -struct SwsContext *sws_alloc_context(void); +SwsContext *sws_alloc_context(void); /** * Initialize the swscaler context sws_context. @@ -185,13 +185,13 @@ struct SwsContext *sws_alloc_context(void); * error */ av_warn_unused_result -int sws_init_context(struct SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter); +int sws_init_context(SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter); /** * Free the swscaler context swsContext. * If swsContext is NULL, then does nothing. */ -void sws_freeContext(struct SwsContext *swsContext); +void sws_freeContext(SwsContext *swsContext); /** * Allocate and return an SwsContext. You need it to perform @@ -214,10 +214,10 @@ void sws_freeContext(struct SwsContext *swsContext); * @note this function is to be removed after a saner alternative is * written */ -struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, - int dstW, int dstH, enum AVPixelFormat dstFormat, - int flags, SwsFilter *srcFilter, - SwsFilter *dstFilter, const double *param); +SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, + int dstW, int dstH, enum AVPixelFormat dstFormat, + int flags, SwsFilter *srcFilter, + SwsFilter *dstFilter, const double *param); /** * Scale the image slice in srcSlice and put the resulting scaled @@ -245,7 +245,7 @@ struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcForm * the destination image * @return the height of the output slice */ -int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], +int sws_scale(SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]); @@ -265,7 +265,7 @@ int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], * * @return 0 on success, a negative AVERROR code on failure */ -int sws_scale_frame(struct SwsContext *c, AVFrame *dst, const AVFrame *src); +int sws_scale_frame(SwsContext *c, AVFrame *dst, const AVFrame *src); /** * Initialize the scaling process for a given pair of source/destination frames. @@ -292,7 +292,7 @@ int sws_scale_frame(struct SwsContext *c, AVFrame *dst, const AVFrame *src); * * @see sws_frame_end() */ -int sws_frame_start(struct SwsContext *c, AVFrame *dst, const AVFrame *src); +int sws_frame_start(SwsContext *c, AVFrame *dst, const AVFrame *src); /** * Finish the scaling process for a pair of source/destination frames previously @@ -302,7 +302,7 @@ int sws_frame_start(struct SwsContext *c, AVFrame *dst, const AVFrame *src); * * @param c The scaling context */ -void sws_frame_end(struct SwsContext *c); +void sws_frame_end(SwsContext *c); /** * Indicate that a horizontal slice of input data is available in the source @@ -316,7 +316,7 @@ void sws_frame_end(struct SwsContext *c); * * @return a non-negative number on success, a negative AVERROR code on failure. */ -int sws_send_slice(struct SwsContext *c, unsigned int slice_start, +int sws_send_slice(SwsContext *c, unsigned int slice_start, unsigned int slice_height); /** @@ -336,7 +336,7 @@ int sws_send_slice(struct SwsContext *c, unsigned int slice_start, * output can be produced * another negative AVERROR code on other kinds of scaling failure */ -int sws_receive_slice(struct SwsContext *c, unsigned int slice_start, +int sws_receive_slice(SwsContext *c, unsigned int slice_start, unsigned int slice_height); /** @@ -347,7 +347,7 @@ int sws_receive_slice(struct SwsContext *c, unsigned int slice_start, * Slice offsets and sizes passed to sws_receive_slice() must be * multiples of the value returned from this function. */ -unsigned int sws_receive_slice_alignment
[FFmpeg-devel] [PATCH 13/19] swscale: organize and better document flags
From: Niklas Haas Group them into an enum rather than random #defines, and document their behavior a bit more obviously. Of particular note, I discovered that SWS_DIRECT_BGR is not referenced anywhere else in the code base. As such, I have moved it to the deprecated section, alongside SWS_ERROR_DIFFUSION. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/swscale.h | 116 --- 1 file changed, 66 insertions(+), 50 deletions(-) diff --git a/libswscale/swscale.h b/libswscale/swscale.h index f3ee93984b..a98285685b 100644 --- a/libswscale/swscale.h +++ b/libswscale/swscale.h @@ -91,6 +91,71 @@ typedef enum SwsAlphaBlend { SWS_ALPHA_BLEND_NB, /* not part of the ABI */ } SwsAlphaBlend; +typedef enum SwsFlags { +/** + * Scaler selection options. Only one may be active at a time. + */ +SWS_FAST_BILINEAR = 1 << 0, ///< fast bilinear filtering +SWS_BILINEAR = 1 << 1, ///< bilinear filtering +SWS_BICUBIC = 1 << 2, ///< 2-tap cubic B-spline +SWS_X = 1 << 3, ///< experimental +SWS_POINT = 1 << 4, ///< nearest neighbor +SWS_AREA = 1 << 5, ///< area averaging +SWS_BICUBLIN = 1 << 6, ///< bicubic luma, bilinear chroma +SWS_GAUSS = 1 << 7, ///< gaussian approximation +SWS_SINC = 1 << 8, ///< unwindowed sinc +SWS_LANCZOS = 1 << 9, ///< 3-tap sinc/sinc +SWS_SPLINE= 1 << 10, ///< cubic Keys spline + +/** + * Emit verbose log of scaling parameters. + */ +SWS_PRINT_INFO= 1 << 12, ///< log scaling parameters + +/** + * Perform full chroma upsampling when upscaling to RGB. + * + * For example, when converting 50x50 yuv420p to 100x100 rgba, setting this flag + * will scale the chroma plane from 25x25 to 100x100 (4:4:4), and then convert + * the 100x100 yuv444p image to rgba in the final output step. + * + * Without this flag, the chroma plane is instead scaled to 50x100 (4:2:2), + * with a single chroma sample being re-used for both of the horizontally + * adjacent RGBA output pixels. + */ +SWS_FULL_CHR_H_INT = 1 << 13, + +/** + * Perform full chroma interpolation when downscaling RGB sources. + * + * For example, when converting a 100x100 rgba source to 50x50 yuv444p, setting + * this flag will generate a 100x100 (4:4:4) chroma plane, which is then + * downscaled to the required 50x50. + * + * Without this flag, the chroma plane is instead generated at 50x100 (dropping + * every other pixel), before then being downscaled to the required 50x50 + * resolution. + */ +SWS_FULL_CHR_H_INP = 1 << 14, + +/** + * Force bit-exact output. This will prevent the use of platform-specific + * optimizations that may lead to slight difference in rounding, in favor + * of always maintaining exact bit output compatibility with the reference + * C code. + * + * Note: It is recommended to set both of these flags simultaneously. + */ +SWS_ACCURATE_RND = 1 << 18, +SWS_BITEXACT = 1 << 19, + +/** + * Deprecated flags. + */ +SWS_DIRECT_BGR = 1 << 15, ///< this flag has no effect +SWS_ERROR_DIFFUSION = 1 << 23, ///< Set `SwsContext.dither` instead +} SwsFlags; + /*** * Context creation and management * ***/ @@ -114,7 +179,7 @@ typedef struct SwsContext { void *opaque; /** - * Bitmask of SWS_*. + * Bitmask of SWS_*. See `SwsFlags` for details. */ int64_t flags; @@ -229,60 +294,11 @@ int sws_test_frame(const AVFrame *frame, int output); */ int sws_is_noop(const AVFrame *dst, const AVFrame *src); -/* values for the flags, the stuff on the command line is different */ -#define SWS_FAST_BILINEAR 1 -#define SWS_BILINEAR 2 -#define SWS_BICUBIC 4 -#define SWS_X 8 -#define SWS_POINT 0x10 -#define SWS_AREA 0x20 -#define SWS_BICUBLIN 0x40 -#define SWS_GAUSS 0x80 -#define SWS_SINC 0x100 -#define SWS_LANCZOS 0x200 -#define SWS_SPLINE0x400 - #define SWS_SRC_V_CHR_DROP_MASK 0x3 #define SWS_SRC_V_CHR_DROP_SHIFT16 #define SWS_PARAM_DEFAULT 123456 -#define SWS_PRINT_INFO 0x1000 - -//the following 3 flags are not completely implemented - -/** - * Perform full chroma upsampling when upscaling to RGB. - * - * For example, when converting 50x50 yuv420p to 100x100 rgba, setting this flag - * will scale the chroma plane from 25x25 to 100x100 (4:4:4), and then convert - * the 100x100 yuv444p image to rgba in the final output step. - * - * Without this flag, the chroma plane is instead scaled to 50x100 (4:2:2), - * with a single chroma sample being re-used for both of the horizontally - * adjacent RGBA output pixels. - */ -#define SWS
[FFmpeg-devel] [PATCH 04/19] swscale: add sws_free_context()
From: Niklas Haas Merely a convenience wrapper around sws_freeContext(). The name change is for parity with the other sws_* functions. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/swscale.h | 7 +++ libswscale/utils.c | 10 ++ 2 files changed, 17 insertions(+) diff --git a/libswscale/swscale.h b/libswscale/swscale.h index b5dea09bef..f9fd340240 100644 --- a/libswscale/swscale.h +++ b/libswscale/swscale.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2024 Niklas Haas * Copyright (C) 2001-2011 Michael Niedermayer * * This file is part of FFmpeg. @@ -78,6 +79,12 @@ const AVClass *sws_get_class(void); */ SwsContext *sws_alloc_context(void); +/** + * Free the context and everything associated with it, and write NULL + * to the provided pointer. + */ +void sws_free_context(SwsContext **ctx); + /* values for the flags, the stuff on the command line is different */ #define SWS_FAST_BILINEAR 1 #define SWS_BILINEAR 2 diff --git a/libswscale/utils.c b/libswscale/utils.c index b75c9a2bb4..d80a3f0a80 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -2514,6 +2514,16 @@ void sws_freeContext(SwsContext *sws) av_free(sws); } +void sws_free_context(SwsContext **pctx) +{ +SwsContext *ctx = *pctx; +if (!ctx) +return; + +sws_freeContext(ctx); +*pctx = NULL; +} + SwsContext *sws_getCachedContext(SwsContext *sws, int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, -- 2.46.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 03/19] swscale: slightly reorder header
From: Niklas Haas I want to start grouping "legacy" functions which I tend to deprecate together, away from the new ones. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/swscale.h | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libswscale/swscale.h b/libswscale/swscale.h index 2604eb1624..b5dea09bef 100644 --- a/libswscale/swscale.h +++ b/libswscale/swscale.h @@ -41,6 +41,8 @@ #include "version.h" #endif +typedef struct SwsContext SwsContext; + /** * @defgroup libsws libswscale * Color conversion and scaling library. @@ -61,6 +63,21 @@ const char *swscale_configuration(void); */ const char *swscale_license(void); +/** + * Get the AVClass for swsContext. It can be used in combination with + * AV_OPT_SEARCH_FAKE_OBJ for examining options. + * + * @see av_opt_find(). + */ +const AVClass *sws_get_class(void); + +/** + * Allocate an empty SwsContext. This must be filled and passed to + * sws_init_context(). For filling see AVOptions, options.c and + * sws_setColorspaceDetails(). + */ +SwsContext *sws_alloc_context(void); + /* values for the flags, the stuff on the command line is different */ #define SWS_FAST_BILINEAR 1 #define SWS_BILINEAR 2 @@ -150,8 +167,6 @@ typedef struct SwsFilter { SwsVector *chrV; } SwsFilter; -typedef struct SwsContext SwsContext; - /** * Return a positive value if pix_fmt is a supported input format, 0 * otherwise. @@ -171,13 +186,6 @@ int sws_isSupportedOutput(enum AVPixelFormat pix_fmt); */ int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt); -/** - * Allocate an empty SwsContext. This must be filled and passed to - * sws_init_context(). For filling see AVOptions, options.c and - * sws_setColorspaceDetails(). - */ -SwsContext *sws_alloc_context(void); - /** * Initialize the swscaler context sws_context. * @@ -445,14 +453,6 @@ void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pix */ void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette); -/** - * Get the AVClass for swsContext. It can be used in combination with - * AV_OPT_SEARCH_FAKE_OBJ for examining options. - * - * @see av_opt_find(). - */ -const AVClass *sws_get_class(void); - /** * @} */ -- 2.46.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 15/19] swscale/graph: add new high-level scaler dispatch mechanism
From: Niklas Haas This interface has been designed from the ground up to serve as a new framework for dispatching various scaling operations at a high level. This will eventually replace the old ad-hoc system of using cascaded contexts, as well as allowing us to plug in more dynamic scaling passes requiring intermediate steps, such as colorspace conversions, etc. The starter implementation merely piggybacks off the existing sws_init() and sws_scale(), functions, though it does bring the immediate improvement of splitting up cascaded functions and pre/post conversion functions into separate filter passes, which allows them to e.g. be executed in parallel even when the main scaler is required to be single threaded. Follow-up commits will eventually expand this to move all of the scaling decision logic into the graph init function, and also eliminate some of the current special cases. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/Makefile | 1 + libswscale/graph.c | 501 libswscale/graph.h | 123 +++ 3 files changed, 625 insertions(+) create mode 100644 libswscale/graph.c create mode 100644 libswscale/graph.h diff --git a/libswscale/Makefile b/libswscale/Makefile index 757997b401..81f32f4dd7 100644 --- a/libswscale/Makefile +++ b/libswscale/Makefile @@ -9,6 +9,7 @@ OBJS = alphablend.o \ hscale.o \ hscale_fast_bilinear.o \ gamma.o \ + graph.o \ half2float.o \ input.o \ options.o\ diff --git a/libswscale/graph.c b/libswscale/graph.c new file mode 100644 index 00..ac438ae2c0 --- /dev/null +++ b/libswscale/graph.c @@ -0,0 +1,501 @@ +/* + * Copyright (C) 2024 Niklas Haas + * + * 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/avassert.h" +#include "libavutil/error.h" +#include "libavutil/mem.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" +#include "libavutil/slicethread.h" + +#include "libswscale/swscale.h" + +#include "swscale_internal.h" +#include "graph.h" + +/* slice_align should be a power of two, or 0 to disable slice threading */ +static SwsPass *pass_add(SwsGraph *graph, void *priv, int w, int h, + SwsField in, SwsField out, int slice_align) +{ +SwsPass *pass = av_mallocz(sizeof(*pass)); +int ret; + +pass->graph = graph; +pass->input = in; +pass->output = out; +pass->priv = priv; +pass->width = w; +pass->height = h; + +if (!slice_align) { +pass->slice_h = pass->height; +pass->num_slices = 1; +} else { +pass->slice_h = (pass->height + graph->num_threads - 1) / graph->num_threads; +pass->slice_h = FFALIGN(pass->slice_h, slice_align); +pass->num_slices = (pass->height + pass->slice_h - 1) / pass->slice_h; +} + +ret = av_dynarray_add_nofree(&graph->passes, &graph->num_passes, pass); +if (ret < 0) +av_freep(&pass); +return pass; +} + +/* Set output linesize before calling this */ +static int pass_alloc_output(SwsPass *pass) +{ +const int aligned_h = pass->num_slices * pass->slice_h; +const int *linesize = pass->output.linesize; + +size_t offset[4]; +size_t total_size = 0; +for (int i = 0; i < 4; i++) { +const size_t size = FFABS(linesize[i]) * aligned_h; +offset[i] = total_size; +total_size = FFALIGN(total_size + size, 16); +} + +av_assert0(!pass->buf); +pass->buf = av_malloc(total_size); +if (!pass->buf) +return AVERROR(ENOMEM); + +for (int i = 0; i < 4; i++) { +uint8_t *base = pass->buf + offset[i]; +if (linesize[i] < 0) +base -= linesize[i] * (aligned_h - 1); +pass->output.data[i] = linesize[i] ? base : NULL; +} + +return 0; +} + +static void setup_swscale(const SwsField *out, const SwsField *in, + const SwsPass *pass) +{ +SwsInternal
[FFmpeg-devel] [PATCH 17/19] tests/swscale: rewrite on top of new API
From: Niklas Haas This rewrite cleans up the code to use AVFrames and the new swscale API. The log format has also been simplified and expanded to account for the new options. (Not yet implemented) The self testing code path has also been expanded to test the new swscale implementation against the old one, to serve as an unchanging reference. This does not accomplish much yet, but serves as a framework for future work. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/tests/swscale.c | 665 - 1 file changed, 284 insertions(+), 381 deletions(-) diff --git a/libswscale/tests/swscale.c b/libswscale/tests/swscale.c index f9b5f60ef0..c11a46024e 100644 --- a/libswscale/tests/swscale.c +++ b/libswscale/tests/swscale.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2024 Nikles Haas * Copyright (C) 2003-2011 Michael Niedermayer * * This file is part of FFmpeg. @@ -26,424 +27,307 @@ #undef HAVE_AV_CONFIG_H #include "libavutil/cpu.h" -#include "libavutil/imgutils.h" -#include "libavutil/mem.h" -#include "libavutil/avutil.h" -#include "libavutil/crc.h" -#include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "libavutil/lfg.h" #include "libavutil/sfc64.h" +#include "libavutil/frame.h" +#include "libavutil/pixfmt.h" +#include "libavutil/avassert.h" +#include "libavutil/macros.h" #include "libswscale/swscale.h" -/* HACK Duplicated from swscale_internal.h. - * Should be removed when a cleaner pixel format system exists. */ -#define isGray(x) \ -((x) == AV_PIX_FMT_GRAY8 || \ - (x) == AV_PIX_FMT_YA8 || \ - (x) == AV_PIX_FMT_GRAY16BE|| \ - (x) == AV_PIX_FMT_GRAY16LE|| \ - (x) == AV_PIX_FMT_YA16BE || \ - (x) == AV_PIX_FMT_YA16LE) -#define hasChroma(x) \ -(!(isGray(x)|| \ - (x) == AV_PIX_FMT_MONOBLACK || \ - (x) == AV_PIX_FMT_MONOWHITE)) - -static av_always_inline int isALPHA(enum AVPixelFormat pix_fmt) -{ -const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); -return desc->flags & AV_PIX_FMT_FLAG_ALPHA; -} +enum { +WIDTH = 96, +HEIGHT = 96, +}; -static double prob = 1; -FFSFC64 prng_state; +struct options { +enum AVPixelFormat src_fmt; +enum AVPixelFormat dst_fmt; +double prob; +}; -static uint64_t getSSD(const uint8_t *src1, const uint8_t *src2, - int stride1, int stride2, int w, int h) -{ -int x, y; -uint64_t ssd = 0; +struct mode { +SwsFlags flags; +SwsDither dither; +}; -for (y = 0; y < h; y++) { -for (x = 0; x < w; x++) { -int d = src1[x + y * stride1] - src2[x + y * stride2]; -ssd += d * d; -} -} -return ssd; -} +const int dst_w[] = { WIDTH, WIDTH - WIDTH / 3, WIDTH + WIDTH / 3 }; +const int dst_h[] = { HEIGHT, HEIGHT - HEIGHT / 3, HEIGHT + HEIGHT / 3 }; + +const struct mode modes[] = { +{ SWS_FAST_BILINEAR }, +{ SWS_BILINEAR }, +{ SWS_BICUBIC }, +{ SWS_X | SWS_BITEXACT }, +{ SWS_POINT }, +{ SWS_AREA | SWS_ACCURATE_RND }, +{ SWS_BICUBIC | SWS_FULL_CHR_H_INT | SWS_FULL_CHR_H_INP }, +{0}, // test defaults +}; -static uint64_t getSSD0(int ref, const uint8_t *src1, int stride1, -int w, int h) -{ -int x, y; -uint64_t ssd = 0; +static FFSFC64 prng_state; +static SwsContext *sws[3]; /* reused between tests for efficiency */ -for (y = 0; y < h; y++) { -for (x = 0; x < w; x++) { -int d = src1[x + y * stride1] - ref; -ssd += d * d; -} -} -return ssd; +static int fmt_comps(enum AVPixelFormat fmt) +{ +const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); +int comps = desc->nb_components >= 3 ? 0b111 : 0b1; +if (desc->flags & AV_PIX_FMT_FLAG_ALPHA) +comps |= 0b1000; +return comps; } -struct Results { -uint64_t ssdY; -uint64_t ssdU; -uint64_t ssdV; -uint64_t ssdA; -uint32_t crc; -}; - -// test by ref -> src -> dst -> out & compare out against ref -// ref & out are YV12 -static int doTest(const uint8_t * const ref[4], int refStride[4], int w, int h, - enum AVPixelFormat srcFormat, enum AVPixelFormat dstFormat, - int srcW, int srcH, int dstW, int dstH, int flags, - struct Results *r) +static void get_mse(int mse[4], const AVFrame *a, const AVFrame *b, int comps) { -const AVPixFmtDescriptor *desc_yuva420p = av_pix_fmt_desc_get(AV_PIX_FMT_YUVA420P); -const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(srcFormat); -const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(dstFormat); -static enum AVPixelFormat cur_srcFormat; -static int cur_srcW, cur_srcH; -static const uint8_t *src[4]; -static int srcStride[4]; -uint8_t *dst[4] = { 0 }; -uint8_t *out[4] = { 0 }; -int dstStride[4] = {0};
[FFmpeg-devel] [PATCH 16/19] swscale: introduce new, dynamic scaling API
From: Niklas Haas As part of a larger, ongoing effort to modernize and partially rewrite libswscale, it was decided and generally agreed upon to introduce a new public API for libswscale. This API is designed to be less stateful, more explicitly defined, and considerably easier to use than the existing one. Most of the API work has been already accomplished in the previous commits, this commit merely introduces the ability to use sws_scale_frame() dynamically, without prior sws_init_context() calls. Instead, the new API takes frame properties from the frames themselves, and the implementation is based on the new SwsGraph API, which we simply reinitialize as needed. This high-level wrapper also recreates the logic that used to live inside vf_scale for scaling interlaced frames, enabling it to be reused more easily by end users. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/swscale.c | 223 +- libswscale/swscale.h | 91 ++ libswscale/swscale_internal.h | 6 +- libswscale/utils.c| 4 + libswscale/x86/output.asm | 2 +- 5 files changed, 297 insertions(+), 29 deletions(-) diff --git a/libswscale/swscale.c b/libswscale/swscale.c index d5be07193d..2f4221deee 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -1212,19 +1212,232 @@ int sws_receive_slice(SwsContext *sws, unsigned int slice_start, dst, c->frame_dst->linesize, slice_start, slice_height); } +static SwsField get_field(const AVFrame *frame, int field) +{ +SwsField f = { +#define COPY4(x) { x[0], x[1], x[2], x[3] } +.data = COPY4(frame->data), +.linesize = COPY4(frame->linesize), +}; + +if (!(frame->flags & AV_FRAME_FLAG_INTERLACED)) { +av_assert1(!field); +return f; +} + +if (field == FIELD_BOTTOM) { +/* Odd rows, offset by one line */ +const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); +for (int i = 0; i < FF_ARRAY_ELEMS(f.data); i++) { +f.data[i] += f.linesize[i]; +if (desc->flags & AV_PIX_FMT_FLAG_PAL) +break; +} +} + +/* Take only every second line */ +for (int i = 0; i < FF_ARRAY_ELEMS(f.linesize); i++) +f.linesize[i] <<= 1; + +return f; +} + +/* Subset of av_frame_ref() that only copies (video) data buffers */ +static int frame_refcopy(AVFrame *dst, const AVFrame *src) +{ +int ret; + +/* TODO: handle hwframes? */ + +/* copy frame data if it's not refcounted, or if dst buffers exist */ +if (!src->buf[0] || dst->buf[0]) { +if (!dst->data[0]) { +ret = av_frame_get_buffer(dst, 0); +if (ret < 0) +return ret; +} +ret = av_frame_copy(dst, src); +if (ret < 0) +return ret; +return 0; +} + +/* ref the buffers */ +for (int i = 0; i < FF_ARRAY_ELEMS(src->buf); i++) { +if (!src->buf[i]) +continue; +dst->buf[i] = av_buffer_ref(src->buf[i]); +if (!dst->buf[i]) +return AVERROR(ENOMEM); +} + +memcpy(dst->data, src->data, sizeof(src->data)); +memcpy(dst->linesize, src->linesize, sizeof(src->linesize)); +return 0; +} + int sws_scale_frame(SwsContext *sws, AVFrame *dst, const AVFrame *src) { int ret; +SwsInternal *c = sws_internal(sws); +if (!src || !dst) +return AVERROR(EINVAL); + +if (c->frame_src) { +/* Context has been initialized with explicit values, fall back to + * legacy API */ +ret = sws_frame_start(sws, dst, src); +if (ret < 0) +return ret; + +ret = sws_send_slice(sws, 0, src->height); +if (ret >= 0) +ret = sws_receive_slice(sws, 0, dst->height); -ret = sws_frame_start(sws, dst, src); +sws_frame_end(sws); + +return ret; +} + +ret = sws_frame_setup(sws, dst, src); if (ret < 0) return ret; -ret = sws_send_slice(sws, 0, src->height); -if (ret >= 0) -ret = sws_receive_slice(sws, 0, dst->height); +if (src->data[0]) { +SwsGraph *graph = c->graph[0]; +av_assert0(graph); +if (ff_fmt_equal(&graph->dst, &graph->src)) { +ret = frame_refcopy(dst, src); +if (ret < 0) +return ret; +} else { +if (!dst->data[0]) { +ret = av_frame_get_buffer(dst, 0); +if (ret < 0) +return ret; +} + +for (int field = 0; field < 2; field++) { +SwsField dst_field = get_field(dst, field); +SwsField src_field = get_field(src, field); +sws_graph_run(c->graph[field], &dst_field, &src_field); +if (!graph->src.interlaced) +break; +} +} +} + +return 0;
[FFmpeg-devel] [PATCH 19/19] avfilter/vf_scale: switch to new swscale API
From: Niklas Haas Most logic from this filter has been co-opted into swscale itself, allowing the resulting filter to be substantially simpler as it no longer has to worry about context initialization, interlacing, etc. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libavfilter/vf_scale.c | 354 + 1 file changed, 72 insertions(+), 282 deletions(-) diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 3319428d9c..f4859dcd76 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -31,6 +31,7 @@ #include "filters.h" #include "formats.h" #include "framesync.h" +#include "libavutil/pixfmt.h" #include "scale_eval.h" #include "video.h" #include "libavutil/eval.h" @@ -131,10 +132,7 @@ enum EvalMode { typedef struct ScaleContext { const AVClass *class; -struct SwsContext *sws; ///< software scaler context -struct SwsContext *isws[2]; ///< software scaler context for interlaced material -// context used for forwarding options to sws -struct SwsContext *sws_opts; +SwsContext *sws; FFFrameSync fs; /** @@ -149,8 +147,6 @@ typedef struct ScaleContext { int hsub, vsub; ///< chroma subsampling int slice_y;///< top of current output slice -int input_is_pal; ///< set to 1 if the input format is paletted -int output_is_pal; ///< set to 1 if the output format is paletted int interlaced; int uses_ref; @@ -170,10 +166,6 @@ typedef struct ScaleContext { int in_chroma_loc; int out_chroma_loc; -int out_h_chr_pos; -int out_v_chr_pos; -int in_h_chr_pos; -int in_v_chr_pos; int force_original_aspect_ratio; int force_divisible_by; @@ -334,40 +326,24 @@ revert: static av_cold int preinit(AVFilterContext *ctx) { ScaleContext *scale = ctx->priv; -int ret; -scale->sws_opts = sws_alloc_context(); -if (!scale->sws_opts) +scale->sws = sws_alloc_context(); +if (!scale->sws) return AVERROR(ENOMEM); // set threads=0, so we can later check whether the user modified it -ret = av_opt_set_int(scale->sws_opts, "threads", 0, 0); -if (ret < 0) -return ret; +scale->sws->threads = 0; ff_framesync_preinit(&scale->fs); return 0; } -static const int sws_colorspaces[] = { -AVCOL_SPC_UNSPECIFIED, -AVCOL_SPC_RGB, -AVCOL_SPC_BT709, -AVCOL_SPC_BT470BG, -AVCOL_SPC_SMPTE170M, -AVCOL_SPC_FCC, -AVCOL_SPC_SMPTE240M, -AVCOL_SPC_BT2020_NCL, --1 -}; - static int do_scale(FFFrameSync *fs); static av_cold int init(AVFilterContext *ctx) { ScaleContext *scale = ctx->priv; -int64_t threads; int ret; if (ctx->filter == &ff_vf_scale2ref) @@ -407,14 +383,13 @@ static av_cold int init(AVFilterContext *ctx) if (ret < 0) return ret; -if (scale->in_color_matrix != -1 && -!ff_fmt_is_in(scale->in_color_matrix, sws_colorspaces)) { +if (scale->in_color_matrix != -1 && !sws_test_colorspace(scale->in_color_matrix, 0)) { av_log(ctx, AV_LOG_ERROR, "Unsupported input color matrix '%s'\n", av_color_space_name(scale->in_color_matrix)); return AVERROR(EINVAL); } -if (!ff_fmt_is_in(scale->out_color_matrix, sws_colorspaces)) { +if (scale->out_color_matrix != -1 && !sws_test_colorspace(scale->out_color_matrix, 1)) { av_log(ctx, AV_LOG_ERROR, "Unsupported output color matrix '%s'\n", av_color_space_name(scale->out_color_matrix)); return AVERROR(EINVAL); @@ -424,25 +399,18 @@ static av_cold int init(AVFilterContext *ctx) scale->w_expr, scale->h_expr, (char *)av_x_if_null(scale->flags_str, ""), scale->interlaced); if (scale->flags_str && *scale->flags_str) { -ret = av_opt_set(scale->sws_opts, "sws_flags", scale->flags_str, 0); +ret = av_opt_set(scale->sws, "sws_flags", scale->flags_str, 0); if (ret < 0) return ret; } for (int i = 0; i < FF_ARRAY_ELEMS(scale->param); i++) -if (scale->param[i] != DBL_MAX) { -ret = av_opt_set_double(scale->sws_opts, i ? "param1" : "param0", -scale->param[i], 0); -if (ret < 0) -return ret; -} +if (scale->param[i] != DBL_MAX) +scale->sws->scaler_params[i] = scale->param[i]; // use generic thread-count if the user did not set it explicitly -ret = av_opt_get_int(scale->sws_opts, "threads", 0, &threads); -if (ret < 0) -return ret; -if (!threads) -av_opt_set_int(scale->sws_opts, "threads", ff_filter_get_nb_threads(ctx), 0); +if (!scale->sws->threads) +scale->sws->threads = ff_filter_get_nb_threads(ctx); if (ctx->filter != &ff_vf_scale2ref && scale->uses_ref) { AVFilterPad pad = { @@ -464,11 +432,7 @@ static av_cold void uni
[FFmpeg-devel] [PATCH 18/19] tests/swscale: add a benchmarking mode
From: Niklas Haas With the ability to set the thread count as well. This benchmark includes the constant overhead of context initialization. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/tests/swscale.c | 93 -- 1 file changed, 68 insertions(+), 25 deletions(-) diff --git a/libswscale/tests/swscale.c b/libswscale/tests/swscale.c index c11a46024e..f5ad4b3132 100644 --- a/libswscale/tests/swscale.c +++ b/libswscale/tests/swscale.c @@ -31,21 +31,22 @@ #include "libavutil/lfg.h" #include "libavutil/sfc64.h" #include "libavutil/frame.h" +#include "libavutil/opt.h" +#include "libavutil/time.h" #include "libavutil/pixfmt.h" #include "libavutil/avassert.h" #include "libavutil/macros.h" #include "libswscale/swscale.h" -enum { -WIDTH = 96, -HEIGHT = 96, -}; - struct options { enum AVPixelFormat src_fmt; enum AVPixelFormat dst_fmt; double prob; +int w, h; +int threads; +int iters; +int bench; }; struct mode { @@ -53,9 +54,6 @@ struct mode { SwsDither dither; }; -const int dst_w[] = { WIDTH, WIDTH - WIDTH / 3, WIDTH + WIDTH / 3 }; -const int dst_h[] = { HEIGHT, HEIGHT - HEIGHT / 3, HEIGHT + HEIGHT / 3 }; - const struct mode modes[] = { { SWS_FAST_BILINEAR }, { SWS_BILINEAR }, @@ -114,7 +112,8 @@ static void get_mse(int mse[4], const AVFrame *a, const AVFrame *b, int comps) } } -static int scale_legacy(AVFrame *dst, const AVFrame *src, struct mode mode) +static int scale_legacy(AVFrame *dst, const AVFrame *src, struct mode mode, +struct options opts) { SwsContext *sws_legacy; int ret; @@ -131,23 +130,28 @@ static int scale_legacy(AVFrame *dst, const AVFrame *src, struct mode mode) sws_legacy->dst_format = dst->format; sws_legacy->flags = mode.flags; sws_legacy->dither = mode.dither; +sws_legacy->threads= opts.threads; + +if ((ret = sws_init_context(sws_legacy, NULL, NULL)) < 0) +goto error; -ret = sws_init_context(sws_legacy, NULL, NULL); -if (!ret) +for (int i = 0; i < opts.iters; i++) ret = sws_scale_frame(sws_legacy, dst, src); +error: sws_freeContext(sws_legacy); return ret; } /* Runs a series of ref -> src -> dst -> out, and compares out vs ref */ static int run_test(enum AVPixelFormat src_fmt, enum AVPixelFormat dst_fmt, -int dst_w, int dst_h, struct mode mode, const AVFrame *ref, -const int mse_ref[4]) +int dst_w, int dst_h, struct mode mode, struct options opts, +const AVFrame *ref, const int mse_ref[4]) { AVFrame *src = NULL, *dst = NULL, *out = NULL; int mse[4], mse_sws[4], ret = -1; const int comps = fmt_comps(src_fmt) & fmt_comps(dst_fmt); +int64_t time, time_ref = 0; src = av_frame_alloc(); dst = av_frame_alloc(); @@ -174,12 +178,20 @@ static int run_test(enum AVPixelFormat src_fmt, enum AVPixelFormat dst_fmt, sws[1]->flags = mode.flags; sws[1]->dither = mode.dither; -if (sws_scale_frame(sws[1], dst, src) < 0) { -fprintf(stderr, "Failed %s ---> %s\n", av_get_pix_fmt_name(src->format), -av_get_pix_fmt_name(dst->format)); -goto error; +sws[1]->threads = opts.threads; + +time = av_gettime_relative(); + +for (int i = 0; i < opts.iters; i++) { +if (sws_scale_frame(sws[1], dst, src) < 0) { +fprintf(stderr, "Failed %s ---> %s\n", av_get_pix_fmt_name(src->format), +av_get_pix_fmt_name(dst->format)); +goto error; +} } +time = av_gettime_relative() - time; + if (sws_scale_frame(sws[2], out, dst) < 0) { fprintf(stderr, "Failed %s ---> %s\n", av_get_pix_fmt_name(dst->format), av_get_pix_fmt_name(out->format)); @@ -196,11 +208,13 @@ static int run_test(enum AVPixelFormat src_fmt, enum AVPixelFormat dst_fmt, if (!mse_ref) { /* Compare against the legacy swscale API as a reference */ -if (scale_legacy(dst, src, mode) < 0) { +time_ref = av_gettime_relative(); +if (scale_legacy(dst, src, mode, opts) < 0) { fprintf(stderr, "Failed ref %s ---> %s\n", av_get_pix_fmt_name(src->format), av_get_pix_fmt_name(dst->format)); goto error; } +time_ref = av_gettime_relative() - time_ref; if (sws_scale_frame(sws[2], out, dst) < 0) goto error; @@ -221,6 +235,15 @@ static int run_test(enum AVPixelFormat src_fmt, enum AVPixelFormat dst_fmt, } } +if (opts.bench && time_ref) { +printf(" time=%"PRId64" us, ref=%"PRId64" us, speedup=%.3fx %s\n", +time / opts.iters, time_ref / opts.iters, +(double) time_ref / time, +time <= time_ref ? "faster" : "\033[1;33mslower\033[0m"); +} else if (o
[FFmpeg-devel] [PATCH 07/19] swscale: add sws_is_noop()
From: Niklas Haas Exactly what it says on the tin. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/swscale.h | 6 ++ libswscale/utils.c | 7 +++ 2 files changed, 13 insertions(+) diff --git a/libswscale/swscale.h b/libswscale/swscale.h index f36efa4183..d7ea9bd714 100644 --- a/libswscale/swscale.h +++ b/libswscale/swscale.h @@ -139,6 +139,12 @@ int sws_test_transfer(enum AVColorTransferCharacteristic trc, int output); */ int sws_test_frame(const AVFrame *frame, int output); +/** + * Check if a given conversion is a noop. Returns a positive integer if + * no operation needs to be performed, 0 otherwise. + */ +int sws_is_noop(const AVFrame *dst, const AVFrame *src); + /* values for the flags, the stuff on the command line is different */ #define SWS_FAST_BILINEAR 1 #define SWS_BILINEAR 2 diff --git a/libswscale/utils.c b/libswscale/utils.c index 22411d3429..01fe474020 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -2758,3 +2758,10 @@ int sws_test_frame(const AVFrame *frame, int output) const SwsFormat fmt = ff_fmt_from_frame(frame); return ff_test_fmt(&fmt, output); } + +int sws_is_noop(const AVFrame *dst, const AVFrame *src) +{ +SwsFormat dst_fmt = ff_fmt_from_frame(dst); +SwsFormat src_fmt = ff_fmt_from_frame(src); +return ff_fmt_equal(&dst_fmt, &src_fmt); +} -- 2.46.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 14/19] swscale/internal: expose sws_init_single_context() internally
From: Niklas Haas Used by the graph API swscale wrapper, for now. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/swscale_internal.h | 4 libswscale/utils.c| 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 470a9636bb..21d8113e5a 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -955,6 +955,10 @@ extern const int32_t ff_yuv2rgb_coeffs[11][4]; extern const AVClass ff_sws_context_class; +/* Assumes c->opts is already initialized */ +int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter, +SwsFilter *dstFilter); + /** * Set c->convert_unscaled to an unscaled converter if one exists for the * specific source and destination formats, bit depths, flags, etc. diff --git a/libswscale/utils.c b/libswscale/utils.c index d01ab0efc0..04d3f99970 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -1320,8 +1320,8 @@ static enum AVPixelFormat alphaless_fmt(enum AVPixelFormat fmt) } /* Assumes c->opts is already initialized */ -static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter, - SwsFilter *dstFilter) +av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter, +SwsFilter *dstFilter) { int i; int usesVFilter, usesHFilter; -- 2.46.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] Howto utilize GPU acceleration outside expected places?
On 10.10.24 12:35, Anton Khirnov wrote: I have to wonder if it would actually help, given the overhead of copying the data to the GPU and back. Wouldn't it be more useful to write normal SIMD? Yes -- that's indeed very good question! I'm also not convinced that it will always show positive consequences for the actual processing performance, cause of the already mentioned upload/download requirements. It's also very hard to examine this question by empiric means, because the wide range of possible hardware configurations and capabilities makes final answer resp. objective judgment nearly impossible. Nevertheless, I think, solving this kind of tasks by compute shaders looks for nowadays developers more natural and intuitive than spending overly efforts on cryptic CPU based SIMD optimizations, although this other approach is still a valuable field of development. How well it works in practice also depends on optimizations of the already established processing infrastructure, image data exchange pipeline and development advises available within the given framework. One of the main reasons, why I'm interested in this kind of GPU utilization within ffmpeg, isn't so much performance related, but caused by the fact, that the available pixel formats defined by the vulkan hw acceleration subsystem look much more suitable and complete for high end video processing than their sws counterparts. Well -- in fact it's more important that there is a minimal set of common pixel formats which are supported very well on either side and provide an optimized/efficient path for exchange between both worlds, but nearly lossless processing of floating point image data seems to fit much better into this other context. 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 v11 1/3] libavcodec/dnxucdec: DNxUncompressed decoder
Quoting Martin Schitter (2024-10-10 04:58:40) > +static int pass_though(AVCodecContext *avctx, AVFrame *frame, const AVPacket > *avpkt) > +{ > +/* there is no need to copy as the data already match > + * a known pixel format */ > + > +frame->buf[0] = av_buffer_ref(avpkt->buf); > + > +if (!frame->buf[0]) { > +return AVERROR(ENOMEM); > +} > + > +return av_image_fill_arrays(frame->data, frame->linesize, avpkt->data, > + avctx->pix_fmt, avctx->width, avctx->height, > 1); > +} I've already commented on this in a previous version - this should be directly exported as rawvideo by the demuxer rather than requiring a special encoder. > +static int float2planes(AVCodecContext *avctx, AVFrame *frame, const > AVPacket *pkt) > +{ > +int lw; > +const size_t sof = 4; > + > +lw = frame->width; > + > +for(int y = 0; y < frame->height; y++){ > +for(int x = 0; x < frame->width; x++){ > +memcpy(&frame->data[2][sof*(lw*y + x)], &pkt->data[sof* 3*(lw*y > + x)], sof); > +memcpy(&frame->data[0][sof*(lw*y + x)], &pkt->data[sof*(3*(lw*y > + x) + 1)], sof); > +memcpy(&frame->data[1][sof*(lw*y + x)], &pkt->data[sof*(3*(lw*y > + x) + 2)], sof); > +} > +} Same here, deinterleaving packed to planar is a job for swscale. > +return pkt->size; > +} > + > +static int half_add_alpha(AVCodecContext *avctx, AVFrame *frame, const > AVPacket *pkt) > +{ > +/* ffmpeg doesn't provide any Float16 RGB pixel format without alpha > channel > + * right now. As workaround we simply add an opaque alpha layer. */ So why not add the format then? -- Anton Khirnov ___ 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/vp56: decode interlace content
Quoting Peter Ross (2024-10-09 07:35:08) > Modification of patch submitted by Aurelien Jacobs (November 2007). > > Fixes ticket #5581. > --- > libavcodec/vp5.c | 5 + > libavcodec/vp56.c| 32 +++- > libavcodec/vp56.h| 6 ++ > libavcodec/vp6.c | 11 ++- > libavcodec/vp6data.h | 11 +++ > 5 files changed, 55 insertions(+), 10 deletions(-) Should the result not be flagged as interlaced? Also, would be nice to have a test. -- Anton Khirnov ___ 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 4/4] fate/all: add missing crc/framecrc/md5/framemd5/pipe dependencies
>>-FATE_SAMPLES_DEMUX-$(call ALLYES, S337M_DEMUXER DOLBY_E_PARSER >>FRAMECRC_MUXER) += fate-s337m-demux >>+FATE_SAMPLES_DEMUX-$(call FRAMECRC, S337M,, DOLBY_E_PARSER >>+FRAMECRC_MUXER) += fate-s337m-demux >> fate-s337m-demux: CMD = framecrc -i $(TARGET_SAMPLES)/dolby_e/16-11 -c >> copy -ss 2 -t 1 > >Ooops, I failed to remove the redundant FRAMECRC_MUXER here. >I'll send a v2 early next week including other potential feedbacks if any. > >Nicolas By the way, maybe I should have mentioned it, but I inserted many "call FRAMECRC" which may add some unrequired dependencies when streamcopying like here. I think it is acceptable as a comment in the Makefile already states that PCM_S16LE_ENCODER and RAWVIDEO_ENCODER may be required although not necessary. It is some kind of compromise to avoid numerous overlapping macros, and I guess anyone wanting a serious fate would have pcm_s16 and rawvideo encoders enabled. Nicolas ___ 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] Howto utilize GPU acceleration outside expected places?
On 10.10.24 11:27, Lynne via ffmpeg-devel wrote: Petro Mozil wrote a Vulkan VC-2 decoder that'll soon get merged: https://github.com/pmozil/FFmpeg Thanks for this very useful link! I'll definitely have to study this uncommon vulkan dirac implementation and learn from it. Its an example on how to accelerate via compute shaders. What he did was he simply introduced vc2_vulkan as a hwaccel. It makes sense, even for partially accelerated codecs, since the hwaccel infrastructure handles everything for you, **including a fallback for CPU decoding**, and users automatically get accelerated support. Interesting! -- I wouldn't have expected this behavior... I still have to look at more closely at this topic, but thanks again for this really instructive hint! 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".
[FFmpeg-devel] [PATCH 12/19] swscale: expose SwsContext publicly
From: Niklas Haas Following in the footsteps of the work in the previous commit, it's now relatively straightforward to expose the options struct publicly as SwsContext. This is a step towards making this more user friendly, as well as following API conventions established elsewhere. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/options.c | 3 +- libswscale/swscale.c | 2 +- libswscale/swscale.h | 102 +++-- libswscale/swscale_internal.h | 49 ++ libswscale/utils.c| 165 +- libswscale/x86/output.asm | 2 +- tests/checkasm/sw_scale.c | 8 +- 7 files changed, 187 insertions(+), 144 deletions(-) diff --git a/libswscale/options.c b/libswscale/options.c index 6248e5f4b5..4ce7d8a36a 100644 --- a/libswscale/options.c +++ b/libswscale/options.c @@ -27,7 +27,7 @@ static const char *sws_context_to_name(void *ptr) return "swscaler"; } -#define OFFSET(x) offsetof(SwsInternal, opts.x) +#define OFFSET(x) offsetof(SwsContext, x) #define DEFAULT 0 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM @@ -91,7 +91,6 @@ const AVClass ff_sws_context_class = { .class_name = "SWScaler", .item_name = sws_context_to_name, .option = swscale_options, -.parent_log_context_offset = offsetof(SwsInternal, parent), .category = AV_CLASS_CATEGORY_SWSCALER, .version= LIBAVUTIL_VERSION_INT, }; diff --git a/libswscale/swscale.c b/libswscale/swscale.c index ea4c7b00d1..d5be07193d 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -1252,7 +1252,7 @@ int attribute_align_arg sws_scale(SwsContext *sws, void ff_sws_slice_worker(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads) { -SwsInternal *parent = priv; +SwsInternal *parent = sws_internal(priv); SwsContext *sws = parent->slice_ctx[threadnr]; SwsInternal *c = sws_internal(sws); diff --git a/libswscale/swscale.h b/libswscale/swscale.h index d7ea9bd714..f3ee93984b 100644 --- a/libswscale/swscale.h +++ b/libswscale/swscale.h @@ -42,8 +42,6 @@ #include "version.h" #endif -typedef struct SwsContext SwsContext; - /** * @defgroup libsws libswscale * Color conversion and scaling library. @@ -65,17 +63,103 @@ const char *swscale_configuration(void); const char *swscale_license(void); /** - * Get the AVClass for swsContext. It can be used in combination with + * Get the AVClass for SwsContext. It can be used in combination with * AV_OPT_SEARCH_FAKE_OBJ for examining options. * * @see av_opt_find(). */ const AVClass *sws_get_class(void); -/** - * Allocate an empty SwsContext. This must be filled and passed to - * sws_init_context(). For filling see AVOptions, options.c and - * sws_setColorspaceDetails(). +/** + * Flags and quality settings * + **/ + +typedef enum SwsDither { +SWS_DITHER_NONE = 0, /* disable dithering */ +SWS_DITHER_AUTO, /* auto-select from preset */ +SWS_DITHER_BAYER,/* ordered dither matrix */ +SWS_DITHER_ED, /* error diffusion */ +SWS_DITHER_A_DITHER, /* arithmetic addition */ +SWS_DITHER_X_DITHER, /* arithmetic xor */ +SWS_DITHER_NB, /* not part of the ABI */ +} SwsDither; + +typedef enum SwsAlphaBlend { +SWS_ALPHA_BLEND_NONE = 0, +SWS_ALPHA_BLEND_UNIFORM, +SWS_ALPHA_BLEND_CHECKERBOARD, +SWS_ALPHA_BLEND_NB, /* not part of the ABI */ +} SwsAlphaBlend; + +/*** + * Context creation and management * + ***/ + +/** + * Main external API structure. New fields can be added to the end with + * minor version bumps. Removal, reordering and changes to existing fields + * require a major version bump. sizeof(SwsContext) is not part of the ABI. + */ +typedef struct SwsContext { +const AVClass *av_class; + +/** + * Private context used for internal data. + */ +struct SwsInternal *internal; + +/** + * Private data of the user, can be used to carry app specific stuff. + */ +void *opaque; + +/** + * Bitmask of SWS_*. + */ +int64_t flags; + +/** + * Extra parameters for fine-tuning certain scalers. + */ +double scaler_params[2]; + +/** + * How many threads to use for processing, or 0 for automatic selection. + */ +int threads; + +/** + * Dither mode. + */ +SwsDither dither; + +/** + * Alpha blending mode. See `SwsAlphaBlend` for details. + */ +SwsAlphaBlend alpha_blend; + +/** + * Use gamma correct scaling. + */ +int gamma_flag; + +/** + * Frame property overrides. + */ +int src_w, src_h; ///< Width and height of the source frame +int dst_w, dst_h; ///< Width and height of the destination frame +int src_format;///< Source pixel format +int dst
[FFmpeg-devel] [PATCH 08/19] swscale/options: cosmetic changes
From: Niklas Haas Reorganize the list, fix whitespace, make indentation consistent, and rename some descriptions for clarity, consistency or informativeness. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/options.c | 86 ++-- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/libswscale/options.c b/libswscale/options.c index 56b1d2235d..e64e289cf3 100644 --- a/libswscale/options.c +++ b/libswscale/options.c @@ -32,55 +32,57 @@ static const char *sws_context_to_name(void *ptr) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption swscale_options[] = { -{ "sws_flags", "scaler flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, { .i64 = SWS_BICUBIC}, 0, UINT_MAX, VE, .unit = "sws_flags" }, -{ "fast_bilinear", "fast bilinear", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_FAST_BILINEAR }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "bilinear","bilinear", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_BILINEAR }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "bicubic", "bicubic", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_BICUBIC}, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "experimental","experimental", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_X }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "neighbor","nearest neighbor", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_POINT }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "area","averaging area",0, AV_OPT_TYPE_CONST, { .i64 = SWS_AREA }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "bicublin","luma bicubic, chroma bilinear", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_BICUBLIN }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "gauss", "Gaussian", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_GAUSS }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "sinc","sinc", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_SINC }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "lanczos", "Lanczos", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_LANCZOS}, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "spline", "natural bicubic spline",0, AV_OPT_TYPE_CONST, { .i64 = SWS_SPLINE }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "print_info", "print info",0, AV_OPT_TYPE_CONST, { .i64 = SWS_PRINT_INFO }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "accurate_rnd","accurate rounding", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_ACCURATE_RND }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "full_chroma_int", "full chroma interpolation", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_FULL_CHR_H_INT }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "full_chroma_inp", "full chroma input", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_FULL_CHR_H_INP }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "bitexact","", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_BITEXACT }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, -{ "error_diffusion", "error diffusion dither",0, AV_OPT_TYPE_CONST, { .i64 = SWS_ERROR_DIFFUSION}, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, +{ "sws_flags", "swscale flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, { .i64 = SWS_BICUBIC}, .flags = VE, .unit = "sws_flags", .max = UINT_MAX }, +{ "fast_bilinear", "fast bilinear", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_FAST_BILINEAR }, .flags = VE, .unit = "sws_flags" }, +{ "bilinear","bilinear", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_BILINEAR }, .flags = VE, .unit = "sws_flags" }, +{ "bicubic", "bicubic", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_BICUBIC}, .flags = VE, .unit = "sws_flags" }, +{ "experimental","experimental", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_X }, .flags = VE, .unit = "sws_flags" }, +{ "neighbor","nearest neighbor", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_POINT }, .flags = VE, .unit = "sws_flags" }, +{ "area","averaging area",
[FFmpeg-devel] [PATCH 10/19] swscale/x86: use dedicated int for self-modifying MMX dstW
From: Niklas Haas I want to pull options out of SwsInternal, so we need to make this field a dedicated int that gets updated as appropriate in ff_swscale(). Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/swscale.c | 1 + libswscale/swscale_internal.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libswscale/swscale.c b/libswscale/swscale.c index c368c68fea..e0a9e0279f 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -488,6 +488,7 @@ int ff_swscale(SwsInternal *c, const uint8_t *const src[], const int srcStride[] #if HAVE_MMX_INLINE ff_updateMMXDitherTables(c, dstY); +c->dstW_mmx = c->dstW; #endif if (should_dither) { c->chrDither8 = ff_dither_8x8_128[chrDstY & 7]; diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 9b346c4fd9..b58d1bb12a 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -352,6 +352,7 @@ struct SwsInternal { SwsFunc convert_unscaled; int srcW; ///< Width of source luma/alpha planes. int srcH; ///< Height of source luma/alpha planes. +int dstW; ///< Width of destination luma/alpha planes. int dstH; ///< Height of destination luma/alpha planes. int chrSrcW; ///< Width of source chroma planes. int chrSrcH; ///< Height of source chroma planes. @@ -541,7 +542,7 @@ struct SwsInternal { DECLARE_ALIGNED(8, uint64_t, vOffset); int32_t lumMmxFilter[4 * MAX_FILTER_SIZE]; int32_t chrMmxFilter[4 * MAX_FILTER_SIZE]; -int dstW; ///< Width of destination luma/alpha planes. +int dstW_mmx; DECLARE_ALIGNED(8, uint64_t, esp); DECLARE_ALIGNED(8, uint64_t, vRounder); DECLARE_ALIGNED(8, uint64_t, u_temp); -- 2.46.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 05/19] swscale/utils: add SwsFormat abstraction and helpers
From: Niklas Haas Groups together all relevant color metadata from an AVFrame. While we could use AVFrame directly, keeping it a separate struct has three advantages: 1. Functions accepting an SwsFormat will definitely not care about the data pointers. 2. It clearly separates sanitized and raw metadata, since the function to construct an SwsFormat from an AVFrame will also sanitize. 3. It's slightly more lightweight to pass around. Move these into a new header file "utils.h" to avoid crowding swscale_internal.h even more, and also to solve a circular dependency issue down the line. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/utils.c | 65 ++ libswscale/utils.h | 70 ++ 2 files changed, 135 insertions(+) create mode 100644 libswscale/utils.h diff --git a/libswscale/utils.c b/libswscale/utils.c index d80a3f0a80..074be65410 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2024 Niklas Haas * Copyright (C) 2001-2003 Michael Niedermayer * * This file is part of FFmpeg. @@ -59,6 +60,7 @@ #include "rgb2rgb.h" #include "swscale.h" #include "swscale_internal.h" +#include "utils.h" typedef struct FormatEntry { uint8_t is_supported_in :1; @@ -2647,3 +2649,66 @@ int ff_range_add(RangeList *rl, unsigned int start, unsigned int len) return 0; } + +/** + * This function also sanitizes and strips the input data, removing irrelevant + * fields for certain formats. + */ +SwsFormat ff_fmt_from_frame(const AVFrame *frame) +{ +const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); +SwsFormat fmt = { +.width = frame->width, +.height = frame->height, +.format = frame->format, +.range = frame->color_range, +.prim = frame->color_primaries, +.trc= frame->color_trc, +.csp= frame->colorspace, +.loc= frame->chroma_location, +.desc = desc, +}; + +av_assert1(fmt.width > 0); +av_assert1(fmt.height > 0); +av_assert1(fmt.format != AV_PIX_FMT_NONE); +av_assert0(desc); +if (desc->flags & (AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_BAYER)) { +/* RGB-like family */ +fmt.csp = AVCOL_SPC_RGB; +fmt.range = AVCOL_RANGE_JPEG; +} else if (desc->flags & AV_PIX_FMT_FLAG_XYZ) { +fmt.csp = AVCOL_SPC_UNSPECIFIED; +fmt.prim = AVCOL_PRI_SMPTE428; +fmt.trc = AVCOL_TRC_SMPTE428; +} else if (desc->nb_components < 3) { +/* Grayscale formats */ +fmt.prim = AVCOL_PRI_UNSPECIFIED; +fmt.csp = AVCOL_SPC_UNSPECIFIED; +if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) +fmt.range = AVCOL_RANGE_UNSPECIFIED; +else +fmt.range = AVCOL_RANGE_JPEG; // FIXME: this restriction should be lifted +} + +switch (frame->format) { +case AV_PIX_FMT_YUVJ420P: +case AV_PIX_FMT_YUVJ411P: +case AV_PIX_FMT_YUVJ422P: +case AV_PIX_FMT_YUVJ444P: +case AV_PIX_FMT_YUVJ440P: +fmt.range = AVCOL_RANGE_JPEG; +break; +} + +if (!desc->log2_chroma_w && !desc->log2_chroma_h) +fmt.loc = AVCHROMA_LOC_UNSPECIFIED; + +if (frame->flags & AV_FRAME_FLAG_INTERLACED) { +av_assert1(!(fmt.height & 1)); +fmt.height >>= 1; +fmt.interlaced = 1; +} + +return fmt; +} diff --git a/libswscale/utils.h b/libswscale/utils.h new file mode 100644 index 00..3d0b08ffe1 --- /dev/null +++ b/libswscale/utils.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2024 Niklas Haas + * + * 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 SWSCALE_UTILS_H +#define SWSCALE_UTILS_H + +#include "libavutil/pixdesc.h" + +#include "swscale.h" + +/* Subset of AVFrame parameters that uniquely determine pixel representation */ +typedef struct SwsFormat { +int width, height; +int interlaced; +enum AVPixelFormat format; +enum AVColorRange range; +enum AVColorPrimaries prim; +enum AVColorTransferCharacteristic trc; +enum AVColorSpace csp; +enum AVChromaLocation loc; +const AVPixFmtDescriptor *desc; /* convenience */ +} SwsFo
[FFmpeg-devel] [PATCH 09/19] swscale/internal: use static_assert for enforcing offsets
From: Niklas Haas Instead of sprinkling av_assert0 into random init functions. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/swscale_internal.h | 9 + libswscale/utils.c| 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 1817815b01..9b346c4fd9 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -22,6 +22,7 @@ #define SWSCALE_SWSCALE_INTERNAL_H #include +#include #include "config.h" #include "swscale.h" @@ -704,6 +705,14 @@ struct SwsInternal { }; //FIXME check init (where 0) +static_assert(offsetof(SwsInternal, redDither) + DITHER32_INT == offsetof(SwsInternal, dither32), + "dither32 must be at the same offset as redDither + DITHER32_INT"); + +/* x86 yuv2gbrp uses the SwsInternal for yuv coefficients + if struct offsets change the asm needs to be updated too */ +static_assert(offsetof(SwsInternal, yuv2rgb_y_offset) == 40292, + "yuv2rgb_y_offset must be updated in x86 asm"); + SwsFunc ff_yuv2rgb_get_func_ptr(SwsInternal *c); int ff_yuv2rgb_c_init_tables(SwsInternal *c, const int inv_table[4], int fullRange, int brightness, diff --git a/libswscale/utils.c b/libswscale/utils.c index 01fe474020..f5833548a7 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -1227,7 +1227,8 @@ SwsContext *sws_alloc_context(void) { SwsInternal *c = av_mallocz(sizeof(SwsInternal)); -av_assert0(offsetof(SwsInternal, redDither) + DITHER32_INT == offsetof(SwsInternal, dither32)); +static_assert(offsetof(SwsInternal, redDither) + DITHER32_INT == offsetof(SwsInternal, dither32), + "dither32 must be at the same offset as redDither + DITHER32_INT"); if (c) { c->av_class = &ff_sws_context_class; -- 2.46.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 06/19] swscale: add new frame testing API
From: Niklas Haas Replacing the old sws_isSupported* API with a more consistent family of functions that follows the same signature and naming convention, including a placeholder for testing the color space parameters that we don't currently implement conversions for. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/swscale.h | 54 libswscale/utils.c | 46 + libswscale/utils.h | 2 ++ 3 files changed, 102 insertions(+) diff --git a/libswscale/swscale.h b/libswscale/swscale.h index f9fd340240..f36efa4183 100644 --- a/libswscale/swscale.h +++ b/libswscale/swscale.h @@ -85,6 +85,60 @@ SwsContext *sws_alloc_context(void); */ void sws_free_context(SwsContext **ctx); +/*** + * Supported frame formats * + ***/ + +/** + * Test if a given pixel format is supported. + * + * @param output If 0, test if compatible with the source/input frame; + *otherwise, with the destination/output frame. + * @param format The format to check. + * + * @return A positive integer if supported, 0 otherwise. + */ +int sws_test_format(enum AVPixelFormat format, int output); + +/** + * Test if a given color space is supported. + * + * @param output If 0, test if compatible with the source/input frame; + *otherwise, with the destination/output frame. + * @param colorspace The colorspace to check. + * + * @return A positive integer if supported, 0 otherwise. + */ +int sws_test_colorspace(enum AVColorSpace colorspace, int output); + +/** + * Test if a given set of color primaries is supported. + * + * @param output If 0, test if compatible with the source/input frame; + *otherwise, with the destination/output frame. + * @param primaries The color primaries to check. + * + * @return A positive integer if supported, 0 otherwise. + */ +int sws_test_primaries(enum AVColorPrimaries primaries, int output); + +/** + * Test if a given color transfer function is supported. + * + * @param output If 0, test if compatible with the source/input frame; + *otherwise, with the destination/output frame. + * @param trc The color transfer function to check. + * + * @return A positive integer if supported, 0 otherwise. + */ +int sws_test_transfer(enum AVColorTransferCharacteristic trc, int output); + +/** + * Helper function to run all sws_test_* against a frame. Ignores irrelevant + * properties, for example AVColorSpace is not checked for RGB frames. + */ +int sws_test_frame(const AVFrame *frame, int output); + /* values for the flags, the stuff on the command line is different */ #define SWS_FAST_BILINEAR 1 #define SWS_BILINEAR 2 diff --git a/libswscale/utils.c b/libswscale/utils.c index 074be65410..22411d3429 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -2712,3 +2712,49 @@ SwsFormat ff_fmt_from_frame(const AVFrame *frame) return fmt; } + +int sws_test_format(enum AVPixelFormat format, int output) +{ +return output ? sws_isSupportedOutput(format) : sws_isSupportedInput(format); +} + +int sws_test_colorspace(enum AVColorSpace csp, int output) +{ +switch (csp) { +case AVCOL_SPC_UNSPECIFIED: +case AVCOL_SPC_RGB: +case AVCOL_SPC_BT709: +case AVCOL_SPC_BT470BG: +case AVCOL_SPC_SMPTE170M: +case AVCOL_SPC_FCC: +case AVCOL_SPC_SMPTE240M: +case AVCOL_SPC_BT2020_NCL: +return 1; +default: +return 0; +} +} + +int sws_test_primaries(enum AVColorPrimaries prim, int output) +{ +return 1; /* TODO: implement once primaries conversions are supported */ +} + +int sws_test_transfer(enum AVColorTransferCharacteristic trc, int output) +{ +return 1; /* TODO: implement once gamma conversions are supported */ +} + +int ff_test_fmt(const SwsFormat *fmt, int output) +{ +return sws_test_format(fmt->format, output) && + sws_test_colorspace(fmt->csp,output) && + sws_test_primaries (fmt->prim, output) && + sws_test_transfer (fmt->trc,output); +} + +int sws_test_frame(const AVFrame *frame, int output) +{ +const SwsFormat fmt = ff_fmt_from_frame(frame); +return ff_test_fmt(&fmt, output); +} diff --git a/libswscale/utils.h b/libswscale/utils.h index 3d0b08ffe1..6678364abb 100644 --- a/libswscale/utils.h +++ b/libswscale/utils.h @@ -67,4 +67,6 @@ static inline int ff_fmt_align(enum AVPixelFormat fmt) } } +int ff_test_fmt(const SwsFormat *fmt, int output); + #endif /* SWSCALE_UTILS_H */ -- 2.46.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] ffmpeg-patchwork & trac are down/offline
Hi On Fri, Oct 11, 2024 at 12:19:08AM +0300, Dennis Mungai wrote: > Hello there, > > Several domains are down/offline, including: We today rebooted the host on which the VMs are running due to updates. > 2. FFmpeg trac https://trac.ffmpeg.org/ trac seems working as far as i can tell thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB The day soldiers stop bringing you their problems is the day you have stopped leading them. They have either lost confidence that you can help or concluded you do not care. Either case is a failure of leadership. - Colin Powell 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".
Re: [FFmpeg-devel] [PATCH v11 1/3] libavcodec/dnxucdec: DNxUncompressed decoder
On 10.10.24 14:13, Anton Khirnov wrote: Quoting Martin Schitter (2024-10-10 04:58:40) +static int pass_though(AVCodecContext *avctx, AVFrame *frame, const AVPacket *avpkt) +{ +/* there is no need to copy as the data already match + * a known pixel format */ + +frame->buf[0] = av_buffer_ref(avpkt->buf); + +if (!frame->buf[0]) { +return AVERROR(ENOMEM); +} + +return av_image_fill_arrays(frame->data, frame->linesize, avpkt->data, + avctx->pix_fmt, avctx->width, avctx->height, 1); +} I've already commented on this in a previous version - this should be directly exported as rawvideo by the demuxer rather than requiring a special encoder. hmm -- you touched this topic once in an annotation one month ago: On 09.09.24 12:56, Anton Khirnov wrote: > Quoting Martin Schitter (2024-09-08 20:41:38) >> diff --git a/libavcodec/dnxucdec.c b/libavcodec/dnxucdec.c >> new file mode 100644 >> index 000..455c374 >> --- /dev/null >> +++ b/libavcodec/dnxucdec.c >> @@ -0,0 +1,495 @@ >> +/* >> + * Avid DNxUncomressed / SMPTE RDD 50 demuxer > > This says it's a demuxer, while it's implemented as a decoder. > > I'm also wondering if this shouldn't be handled as demuxer exporting > raw video, at least in some of cases if not all. And I quickly responded: On 10.09.24 13:58, martin schitter wrote: > When I started the work, I also thought, it will not require much > more than minimal modifications of MXF related raw data transport > details, but during reverse engineering the actually used dense > bitpacking turned out to be more complicated. > > The codec section should fit rather well for this component, > although large parts of it could be also categorized just as > bitstream filter. Although I accepted all your other suggestions for improvement and rewrote lots of code, I didn't change my mid about this particular topic. And I also didn't get any response or further defense of your point of view concerning this issue until now. I really think, you are wrong in this judgment. There is a good reason, why this new standards about uncompressed payloads were published recently. They describe embedding conditions, are far more complex than just adding simple raw data image streams. Sure, there is no fancy compression or other kind of rocket science involved, but the specified range of possible configuration variants, defined pixel formats and image layer combinations goes for beyond any simplicity expected at first sight. I'm really curious, if this other effort, implementing the uncompressed MP4 payload counterpart, will come to a different conclusion in this regard and get rid of any codec-like file format specific intermediate layer by just extending the [de]muxer? But for DNxUncompressed I really think, the current implementation structure makes sense -- although it just supports the most elementary core features until now and not all those other rarely used capabilities, which would require even more substantial adaptation efforts. +static int float2planes(AVCodecContext *avctx, AVFrame *frame, const AVPacket *pkt) +{ +int lw; +const size_t sof = 4; + +lw = frame->width; + +for(int y = 0; y < frame->height; y++){ +for(int x = 0; x < frame->width; x++){ +memcpy(&frame->data[2][sof*(lw*y + x)], &pkt->data[sof* 3*(lw*y + x)], sof); +memcpy(&frame->data[0][sof*(lw*y + x)], &pkt->data[sof*(3*(lw*y + x) + 1)], sof); +memcpy(&frame->data[1][sof*(lw*y + x)], &pkt->data[sof*(3*(lw*y + x) + 2)], sof); +} +} Same here, deinterleaving packed to planar is a job for swscale. Some of these rather inefficient interleave<->planar conversions where just necessary in practice, because swscale wasn't able to figure out a working pipeline construction otherwise, although in theory the affected pixel format closer to the data input should be supported and work as well!:( At the end I just looked for something that simply works in real world, too! +return pkt->size; +} + +static int half_add_alpha(AVCodecContext *avctx, AVFrame *frame, const AVPacket *pkt) +{ +/* ffmpeg doesn't provide any Float16 RGB pixel format without alpha channel + * right now. As workaround we simply add an opaque alpha layer. */ So why not add the format then? No! -- I definitely don't want to add another ad-hoc provisional solution to swscale! :( That's something, which someone with more experience and familiarity with all the surrounding code base has to create and maintain. I don't think, we need an endless amount of different pixel formats. A useful subset, that really works and provides efficient exchange with hardware acceleration solutions are enough. More exotic redundant variants should be better translated immediately on import/export (e.g. in codecs ;)). But at least this minimal subset, which is requir
Re: [FFmpeg-devel] Howto utilize GPU acceleration outside expected places?
Quoting martin schitter (2024-10-10 10:50:45) > > > On 10.10.24 08:06, Lynne via ffmpeg-devel wrote: > > You can copy libavutil/vulkan* into whatever project you want, and > > change 4 #include lines to make it compile. > > This lets you use the same API to construct and execute shaders as you > > would within lavc/lavfi/lavu into your own project. You will need to > > make libavutil a dependency as hwcontext_vulkan.c cannot be exported and > > must remain within libavutil. > > Thanks for this description and the link. It's very interesting but not > exactly the kind of utilization I'm looking for. > > I don't want to use the ffmpeg vulkan utils in another application, as > demonstrated in your example. I just want to use it within ffmpeg > itself, but slightly different as in all places which I saw until now. > > To bring it to the point: > > I would like to accelerate this trivial 10 and 12bit decoding of > bit-packed-scanlines in my DNxUncompressed implementation using compute > shaders, whenever the required hardware support is available resp. was > enabled on startup and fallback to CPU processing otherwise. I have to wonder if it would actually help, given the overhead of copying the data to the GPU and back. Wouldn't it be more useful to write normal SIMD? -- Anton Khirnov ___ 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] Howto utilize GPU acceleration outside expected places?
On 10/10/2024 10:50, martin schitter wrote: On 10.10.24 08:06, Lynne via ffmpeg-devel wrote: You can copy libavutil/vulkan* into whatever project you want, and change 4 #include lines to make it compile. This lets you use the same API to construct and execute shaders as you would within lavc/lavfi/lavu into your own project. You will need to make libavutil a dependency as hwcontext_vulkan.c cannot be exported and must remain within libavutil. Thanks for this description and the link. It's very interesting but not exactly the kind of utilization I'm looking for. I don't want to use the ffmpeg vulkan utils in another application, as demonstrated in your example. I just want to use it within ffmpeg itself, but slightly different as in all places which I saw until now. To bring it to the point: I would like to accelerate this trivial 10 and 12bit decoding of bit- packed-scanlines in my DNxUncompressed implementation using compute shaders, whenever the required hardware support is available resp. was enabled on startup and fallback to CPU processing otherwise. This is a different usage scenario than utilizing the hardware encoding and decoding facilities provided by vulkan, which seem to be the only kind of vulkan related GPU utilization in libavcodec until now. And because it should be used automatically if available and otherwise fall back to CPU processing it also differs significantly from the vulkan- and placebo filters, which are strictly divided from their CPU counterparts and don't provide any fallback. I simply couldn't find any location in ffmpegs source code, which looks close to this vague idea. Perhaps it's simply impossible for one or the other reason that I do not see -- who knows? I would be happy if you could possibly point me to already existing relevant code in ffmpeg to learn how to develop this kind of behavior as efficient as possible. Petro Mozil wrote a Vulkan VC-2 decoder that'll soon get merged: https://github.com/pmozil/FFmpeg Its an example on how to accelerate via compute shaders. What he did was he simply introduced vc2_vulkan as a hwaccel. It makes sense, even for partially accelerated codecs, since the hwaccel infrastructure handles everything for you, **including a fallback for CPU decoding**, and users automatically get accelerated support. Generally, the flow should be exactly the same as with vulkan_decode.c for video - but instead of writing decoding commands in the command buffer, you run a shader. (this is just an example, vulkan_decode.c is for Vulkan video decoding in specific, you shouldn't use that bit of code, just like Petro didn't). If you need help, IRC, as usual. 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 4/4] fate/all: add missing crc/framecrc/md5/framemd5/pipe dependencies
>De : Nicolas Gaullier >Envoyé : mercredi 9 octobre 2024 22:30 > >diff --git a/tests/fate/demux.mak b/tests/fate/demux.mak >index c16b540d2f..fe5073397e 100644 >--- a/tests/fate/demux.mak >+++ b/tests/fate/demux.mak >@@ -1,82 +1,82 @@ >(..) >-FATE_SAMPLES_DEMUX-$(call ALLYES, S337M_DEMUXER DOLBY_E_PARSER >FRAMECRC_MUXER) += fate-s337m-demux >+FATE_SAMPLES_DEMUX-$(call FRAMECRC, S337M,, DOLBY_E_PARSER FRAMECRC_MUXER) += >fate-s337m-demux > fate-s337m-demux: CMD = framecrc -i $(TARGET_SAMPLES)/dolby_e/16-11 -c copy > -ss 2 -t 1 Ooops, I failed to remove the redundant FRAMECRC_MUXER here. I'll send a v2 early next week including other potential feedbacks if any. Nicolas ___ 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/amfenc: Avoid polling with fixed sleep
Thanks Cameron, your patch timeout mechanism has been tested and improves performance. But still works with some issues when B-frames are presented. This issue was resolved in the attached data, please update your patch with information below: diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c > index 41eaef9758..4c6ee58639 100644 > --- a/libavcodec/amfenc.c > +++ b/libavcodec/amfenc.c > @@ -426,6 +426,8 @@ static int amf_init_encoder(AVCodecContext *avctx) > res = ctx->factory->pVtbl->CreateComponent(ctx->factory, > ctx->context, codec_id, &ctx->encoder); > AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_ENCODER_NOT_FOUND, > "CreateComponent(%ls) failed with error %d\n", codec_id, res); > > +ctx->submitted_frame = 0; > + > return 0; > } > > @@ -541,7 +543,6 @@ static int amf_copy_buffer(AVCodecContext *avctx, > AVPacket *pkt, AMFBuffer *buff > if ((ctx->max_b_frames > 0 || ((ctx->pa_adaptive_mini_gop == 1) ? > true : false)) && ctx->dts_delay == 0) { > int64_t timestamp_last = AV_NOPTS_VALUE; > size_t can_read = av_fifo_can_read(ctx->timestamp_list); > - > AMF_RETURN_IF_FALSE(ctx, can_read > 0, AVERROR_UNKNOWN, > "timestamp_list is empty while max_b_frames = %d\n", > avctx->max_b_frames); > av_fifo_peek(ctx->timestamp_list, ×tamp_last, 1, can_read - > 1); > @@ -787,6 +788,13 @@ int ff_amf_receive_packet(AVCodecContext *avctx, > AVPacket *avpkt) > > av_frame_unref(frame); > ret = av_fifo_write(ctx->timestamp_list, &pts, 1); > + > +if (ctx->submitted_frame == 0) > +{ > +ctx->use_b_frame = (ctx->max_b_frames > 0 || > ((ctx->pa_adaptive_mini_gop == 1) ? true : false)); > +} > +ctx->submitted_frame++; > + > if (ret < 0) > return ret; > } > @@ -796,7 +804,7 @@ int ff_amf_receive_packet(AVCodecContext *avctx, > AVPacket *avpkt) > do { > block_and_wait = 0; > // poll data > -if (!avpkt->data && !avpkt->buf) { > +if (!avpkt->data && !avpkt->buf && (ctx->use_b_frame ? > (ctx->submitted_frame >= 2) : true) ) { > res_query = ctx->encoder->pVtbl->QueryOutput(ctx->encoder, > &data); > if (data) { > // copy data to packet > @@ -806,6 +814,7 @@ int ff_amf_receive_packet(AVCodecContext *avctx, > AVPacket *avpkt) > data->pVtbl->QueryInterface(data, &guid, > (void**)&buffer); // query for buffer interface > ret = amf_copy_buffer(avctx, avpkt, buffer); > > +ctx->submitted_frame++; > buffer->pVtbl->Release(buffer); > > if (data->pVtbl->HasProperty(data, L"av_frame_ref")) { > @@ -843,6 +852,7 @@ int ff_amf_receive_packet(AVCodecContext *avctx, > AVPacket *avpkt) > av_frame_unref(ctx->delayed_frame); > AMF_RETURN_IF_FALSE(ctx, res_resubmit == AMF_OK, > AVERROR_UNKNOWN, "Repeated SubmitInput() failed with error %d\n", > res_resubmit); > > +ctx->submitted_frame++; > ret = av_fifo_write(ctx->timestamp_list, &pts, 1); > if (ret < 0) > return ret; > @@ -861,7 +871,12 @@ int ff_amf_receive_packet(AVCodecContext *avctx, > AVPacket *avpkt) > if (query_output_data_flag == 0) { > if (res_resubmit == AMF_INPUT_FULL || ctx->delayed_drain || > (ctx->eof && res_query != AMF_EOF) || (ctx->hwsurfaces_in_queue >= > ctx->hwsurfaces_in_queue_max)) { > block_and_wait = 1; > -av_usleep(1000); > + > +// Only sleep if the driver doesn't support waiting in > QueryOutput() > +// or if we already have output data so we will skip > calling it. > +if (!ctx->query_timeout_supported || avpkt->data || > avpkt->buf) { > +av_usleep(1000); > +} > } > } > } while (block_and_wait); > diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h > index d985d01bb1..0b8ddd99ed 100644 > --- a/libavcodec/amfenc.h > +++ b/libavcodec/amfenc.h > @@ -68,6 +68,7 @@ typedef struct AmfContext { > > int hwsurfaces_in_queue; > int hwsurfaces_in_queue_max; > +int query_timeout_supported; > > // helpers to handle async calls > int delayed_drain; > @@ -77,6 +78,8 @@ typedef struct AmfContext { > // shift dts back by max_b_frames in timing > AVFifo *timestamp_list; > int64_t dts_delay; > +int submitted_frame; > +amf_booluse_b_frame; > > // common encoder option options > > diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c > index 2a7a782063..f3058c5b96 100644 > --- a/libavcodec/amfenc_av1.c > +++ b/libavcodec/amfenc_av1.c > @@ -467,6 +467,11 @@ FF_ENABLE_DEPRECATION_WARNINGS >
Re: [FFmpeg-devel] [PATCH v1] avformat/dashdec: remove xmlCleanupParser call in dashdec
On 10 Oct 2024, at 17:14, Steven Liu wrote: > Because there have global varible in libxml2, it cleans up memory allocated by > the library itself. It is a cleanup function for the XML library. > It tries to reclaim all related global memory allocated for the library > processing. > It doesn't deallocate any document related memory. > One should call xmlCleanupParser() only when the process has finished using > the library > and all XML/HTML documents built with it. > See also xmlInitParser() which has the opposite function of preparing the > library > for operations. if there are multithreaded or has plugin support calling > this may crash the application if another thread or a plugin is still using > libxml2. > So give a warning message to user for call xmlCleanupParser by themselves. > > Signed-off-by: Steven Liu > --- > libavformat/dashdec.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c > index 99ac6197be..c33ddb9ea4 100644 > --- a/libavformat/dashdec.c > +++ b/libavformat/dashdec.c > @@ -1362,7 +1362,6 @@ static int parse_manifest(AVFormatContext *s, const > char *url, AVIOContext *in) > cleanup: > /*free the document */ > xmlFreeDoc(doc); > -xmlCleanupParser(); > xmlFreeNode(mpd_baseurl_node); > } > > @@ -2026,6 +2025,7 @@ static int dash_read_header(AVFormatContext *s) > if ((ret = ffio_copy_url_options(s->pb, &c->avio_opts)) < 0) > return ret; > > +av_log(s, AV_LOG_WARNING, "Have not call xmlCleanupParser yet, you > should call it by yourself\n"); Ffmpeg CLI users will get this and be very confused, no? (I would be too…) And in general how would application code even go about calling this, given they probably only depend directly on FFmpeg and not necessarily on libxml2 too… Even when applications call this properly, they (and indirectly users) would get this warning anyway possibly thinking there is a bug even when the application did everything right. This is essentially the same issue libcurl has about global initialisation and I do not think there is a satisfying solution for this for Ffmpeg unfortunately. > if ((ret = parse_manifest(s, s->url, s->pb)) < 0) > return ret; > > -- > 2.39.3 (Apple Git-146) > > ___ > 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] avutil/pixdesc: use a bigger variable type when writing bitstream formats
On 10/9/2024 11:05 PM, James Almer wrote: Fixes fate-imgutils and fate-pixelutils under gcc-usan after 29ea34728f1064877a0ab9b8dee0f3de69a2d750. Signed-off-by: James Almer --- libavutil/pixdesc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index f8d6055084..508d6d2a39 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -133,7 +133,7 @@ void av_write_image_line2(const void *src, uint32_t mask = ((1ULL << depth) - 1) << offset; while (w--) { -uint16_t val = src_element_size == 4 ? *src32++ : *src16++; +uint32_t val = src_element_size == 4 ? *src32++ : *src16++; AV_WB32(p, (AV_RB32(p) & ~mask) | (val << offset)); p++; } Will apply. 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 01/21] swscale/input: add AYUV input support
On 10/8/2024 7:50 PM, James Almer wrote: Signed-off-by: James Almer --- libswscale/input.c | 35 +++ libswscale/utils.c | 1 + 2 files changed, 36 insertions(+) Will apply patches 5 to 21 soon. 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 2/3] avcodec/ffv1enc: Prevent generation of files with broken slices
On Tue, Oct 01, 2024 at 10:31:25PM +0200, Michael Niedermayer wrote: > Fixes: Ticket5548 > > Sponsored-by: Sovereign Tech Fund > Signed-off-by: Michael Niedermayer > --- > libavcodec/ffv1.c| 7 +++ > libavcodec/ffv1.h| 1 + > libavcodec/ffv1enc.c | 4 > 3 files changed, 12 insertions(+) will apply [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB "I am not trying to be anyone's saviour, I'm trying to think about the future and not be sad" - Elon Musk 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".
Re: [FFmpeg-devel] [PATCH v2] avcodec/ffv1: Implement CRC with non zero initial and final value
On Thu, Sep 26, 2024 at 10:01:15PM +0200, Michael Niedermayer wrote: > Signed-off-by: Michael Niedermayer > --- > libavcodec/ffv1.h| 1 + > libavcodec/ffv1dec.c | 10 ++ > libavcodec/ffv1enc.c | 12 +--- > 3 files changed, 16 insertions(+), 7 deletions(-) will apply [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Any man who breaks a law that conscience tells him is unjust and willingly accepts the penalty by staying in jail in order to arouse the conscience of the community on the injustice of the law is at that moment expressing the very highest respect for law. - Martin Luther King Jr 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] GSoC Mentor Summit Reimbursement Request
Hello, I would like to request reimbursement for the following expenses incurred attending the Google Summer of Code mentor summit. Description | Amount --+ Train home to London Heathrow | £13.30 Return flight London Heathrow to San Francisco International | £458.89 Taxi San Francisco International to hotel | £55.65 Train London Heathrow to home | £13.30 --+ Total | £541.14 I got a taxi from SFO to the hotel as public transport would have taken ~3x as long and I arrived on the day of the first activities. I understand Google will give FFmpeg $1000 (£766.44 as of writing) to cover these travel expenses, so my trip should be net positive to the coffers overall. -- Frank ___ 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] Howto utilize GPU acceleration outside expected places?
On 10.10.24 08:06, Lynne via ffmpeg-devel wrote: You can copy libavutil/vulkan* into whatever project you want, and change 4 #include lines to make it compile. This lets you use the same API to construct and execute shaders as you would within lavc/lavfi/lavu into your own project. You will need to make libavutil a dependency as hwcontext_vulkan.c cannot be exported and must remain within libavutil. Thanks for this description and the link. It's very interesting but not exactly the kind of utilization I'm looking for. I don't want to use the ffmpeg vulkan utils in another application, as demonstrated in your example. I just want to use it within ffmpeg itself, but slightly different as in all places which I saw until now. To bring it to the point: I would like to accelerate this trivial 10 and 12bit decoding of bit-packed-scanlines in my DNxUncompressed implementation using compute shaders, whenever the required hardware support is available resp. was enabled on startup and fallback to CPU processing otherwise. This is a different usage scenario than utilizing the hardware encoding and decoding facilities provided by vulkan, which seem to be the only kind of vulkan related GPU utilization in libavcodec until now. And because it should be used automatically if available and otherwise fall back to CPU processing it also differs significantly from the vulkan- and placebo filters, which are strictly divided from their CPU counterparts and don't provide any fallback. I simply couldn't find any location in ffmpegs source code, which looks close to this vague idea. Perhaps it's simply impossible for one or the other reason that I do not see -- who knows? I would be happy if you could possibly point me to already existing relevant code in ffmpeg to learn how to develop this kind of behavior as efficient as possible. thanks 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".
[FFmpeg-devel] [PATCH 2/2] lavc/pthread_slice: rename ff_thread_await/report_progress2()
To ff_slice_thread_await/report_progress(). --- libavcodec/hevc/hevcdec.c | 16 libavcodec/pthread_slice.c | 4 ++-- libavcodec/thread.h| 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c index 1f80bbe8ab..c5384c35cc 100644 --- a/libavcodec/hevc/hevcdec.c +++ b/libavcodec/hevc/hevcdec.c @@ -2765,14 +2765,14 @@ static int hls_decode_entry_wpp(AVCodecContext *avctx, void *hevc_lclist, hls_decode_neighbour(lc, l, pps, sps, x_ctb, y_ctb, ctb_addr_ts); if (ctb_row) -ff_thread_await_progress2(s->avctx, ctb_row - 1, - progress + SHIFT_CTB_WPP + 1); +ff_slice_thread_await_progress(s->avctx, ctb_row - 1, + progress + SHIFT_CTB_WPP + 1); /* atomic_load's prototype requires a pointer to non-const atomic variable * (due to implementations via mutexes, where reads involve writes). * Of course, casting const away here is nevertheless safe. */ if (atomic_load((atomic_int*)&s->wpp_err)) { -ff_thread_report_progress2(s->avctx, ctb_row, INT_MAX); +ff_slice_thread_report_progress(s->avctx, ctb_row, INT_MAX); return 0; } @@ -2796,19 +2796,19 @@ static int hls_decode_entry_wpp(AVCodecContext *avctx, void *hevc_lclist, ctb_addr_ts++; ff_hevc_save_states(lc, pps, ctb_addr_ts); -ff_thread_report_progress2(s->avctx, ctb_row, ++progress); +ff_slice_thread_report_progress(s->avctx, ctb_row, ++progress); ff_hevc_hls_filters(lc, l, pps, x_ctb, y_ctb, ctb_size); if (!more_data && (x_ctb+ctb_size) < sps->width && ctb_row != s->sh.num_entry_point_offsets) { /* Casting const away here is safe, because it is an atomic operation. */ atomic_store((atomic_int*)&s->wpp_err, 1); -ff_thread_report_progress2(s->avctx, ctb_row, INT_MAX); +ff_slice_thread_report_progress(s->avctx, ctb_row, INT_MAX); return 0; } if ((x_ctb+ctb_size) >= sps->width && (y_ctb+ctb_size) >= sps->height ) { ff_hevc_hls_filter(lc, l, pps, x_ctb, y_ctb, ctb_size); -ff_thread_report_progress2(s->avctx, ctb_row, INT_MAX); +ff_slice_thread_report_progress(s->avctx, ctb_row, INT_MAX); return ctb_addr_ts; } ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; @@ -2818,14 +2818,14 @@ static int hls_decode_entry_wpp(AVCodecContext *avctx, void *hevc_lclist, break; } } -ff_thread_report_progress2(s->avctx, ctb_row, INT_MAX); +ff_slice_thread_report_progress(s->avctx, ctb_row, INT_MAX); return 0; error: l->tab_slice_address[ctb_addr_rs] = -1; /* Casting const away here is safe, because it is an atomic operation. */ atomic_store((atomic_int*)&s->wpp_err, 1); -ff_thread_report_progress2(s->avctx, ctb_row, INT_MAX); +ff_slice_thread_report_progress(s->avctx, ctb_row, INT_MAX); return ret; } diff --git a/libavcodec/pthread_slice.c b/libavcodec/pthread_slice.c index 93e452e99f..5db449348b 100644 --- a/libavcodec/pthread_slice.c +++ b/libavcodec/pthread_slice.c @@ -180,7 +180,7 @@ int ff_slice_thread_init(AVCodecContext *avctx) return 0; } -void ff_thread_report_progress2(AVCodecContext *avctx, int job, int val) +void ff_slice_thread_report_progress(AVCodecContext *avctx, int job, int val) { SliceThreadContext *p = avctx->internal->thread_ctx; Progress *const progress = &p->progress[job]; @@ -191,7 +191,7 @@ void ff_thread_report_progress2(AVCodecContext *avctx, int job, int val) pthread_mutex_unlock(&progress->mutex); } -void ff_thread_await_progress2(AVCodecContext *avctx, int job, int val) +void ff_slice_thread_await_progress(AVCodecContext *avctx, int job, int val) { SliceThreadContext *p = avctx->internal->thread_ctx; Progress *progress = &p->progress[job]; diff --git a/libavcodec/thread.h b/libavcodec/thread.h index db3ec0b98c..e11facd73d 100644 --- a/libavcodec/thread.h +++ b/libavcodec/thread.h @@ -58,8 +58,8 @@ int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx, int (*main_func)(AVCodecContext *c), void *arg, int *ret, int job_count); int ff_slice_thread_init_progress(AVCodecContext *avctx, int job_count); -void ff_thread_report_progress2(AVCodecContext *avctx, int job, int val); -void ff_thread_await_progress2(AVCodecContext *avctx, int job, int val); +void ff_slice_thread_report_progress(AVCodecContext *avctx, int job, int val); +void ff_slice_thread_await_progress(AVCodecContext *avctx, int job, int val); enum ThreadingStatus { FF_THREAD_IS_COPY, -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To uns
[FFmpeg-devel] [PATCH 1/2] lavc/pthread_slice: unbreak WPP/progress2 code
It currently associates a progress value with a thread rather than a job, relying on the broken assumption that a job's thread number is equal to its job number modulo thread count. This changes the API to associate a mutex/cond/progress value with every job. Since job count may change dynamically, the ff_slice_thread_init_progress() function - previously called in decoder init - is eliminated as there is nothing left for it to do. The per-frame (and previously horribly-misnamed) ff_slice_thread_allocz_entries() takes over the name and the mutex/condvar-initializing role of ff_slice_thread_init_progress(). await/report_progress2() lose their thread argument, as it is no longer used. The misnamed 'field' argument is renamed to 'job', is it is the job whose progress value we are interested in. The functions also no longer peform nontrivial manipulation of the progress target/value, as that hardcodes caller/codec-specific semantics into what should be a generic API. Fixes races and deadlocks in hevdec with slice threading, e.g. some of those mentioned in #11221. --- libavcodec/hevc/hevcdec.c | 26 libavcodec/pthread_slice.c | 125 ++--- libavcodec/thread.h| 8 +-- 3 files changed, 76 insertions(+), 83 deletions(-) diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c index 0dc24f82f8..1f80bbe8ab 100644 --- a/libavcodec/hevc/hevcdec.c +++ b/libavcodec/hevc/hevcdec.c @@ -2751,6 +2751,8 @@ static int hls_decode_entry_wpp(AVCodecContext *avctx, void *hevc_lclist, const uint8_t *data = s->data + s->sh.offset[ctb_row]; const size_t data_size = s->sh.size[ctb_row]; +int progress = 0; + int ret; if (ctb_row) @@ -2762,13 +2764,15 @@ static int hls_decode_entry_wpp(AVCodecContext *avctx, void *hevc_lclist, hls_decode_neighbour(lc, l, pps, sps, x_ctb, y_ctb, ctb_addr_ts); -ff_thread_await_progress2(s->avctx, ctb_row, thread, SHIFT_CTB_WPP); +if (ctb_row) +ff_thread_await_progress2(s->avctx, ctb_row - 1, + progress + SHIFT_CTB_WPP + 1); /* atomic_load's prototype requires a pointer to non-const atomic variable * (due to implementations via mutexes, where reads involve writes). * Of course, casting const away here is nevertheless safe. */ if (atomic_load((atomic_int*)&s->wpp_err)) { -ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP); +ff_thread_report_progress2(s->avctx, ctb_row, INT_MAX); return 0; } @@ -2792,19 +2796,19 @@ static int hls_decode_entry_wpp(AVCodecContext *avctx, void *hevc_lclist, ctb_addr_ts++; ff_hevc_save_states(lc, pps, ctb_addr_ts); -ff_thread_report_progress2(s->avctx, ctb_row, thread, 1); +ff_thread_report_progress2(s->avctx, ctb_row, ++progress); ff_hevc_hls_filters(lc, l, pps, x_ctb, y_ctb, ctb_size); if (!more_data && (x_ctb+ctb_size) < sps->width && ctb_row != s->sh.num_entry_point_offsets) { /* Casting const away here is safe, because it is an atomic operation. */ atomic_store((atomic_int*)&s->wpp_err, 1); -ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP); +ff_thread_report_progress2(s->avctx, ctb_row, INT_MAX); return 0; } if ((x_ctb+ctb_size) >= sps->width && (y_ctb+ctb_size) >= sps->height ) { ff_hevc_hls_filter(lc, l, pps, x_ctb, y_ctb, ctb_size); -ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP); +ff_thread_report_progress2(s->avctx, ctb_row, INT_MAX); return ctb_addr_ts; } ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; @@ -2814,14 +2818,14 @@ static int hls_decode_entry_wpp(AVCodecContext *avctx, void *hevc_lclist, break; } } -ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP); +ff_thread_report_progress2(s->avctx, ctb_row, INT_MAX); return 0; error: l->tab_slice_address[ctb_addr_rs] = -1; /* Casting const away here is safe, because it is an atomic operation. */ atomic_store((atomic_int*)&s->wpp_err, 1); -ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP); +ff_thread_report_progress2(s->avctx, ctb_row, INT_MAX); return ret; } @@ -2909,7 +2913,7 @@ static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal) } atomic_store(&s->wpp_err, 0); -res = ff_slice_thread_allocz_entries(s->avctx, s->sh.num_entry_point_offsets + 1); +res = ff_slice_thread_init_progress(s->avctx, s->sh.num_entry_point_offsets + 1); if (res < 0) return res; @@ -3981,12 +3985,6 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) HEVCContext *s = avctx->priv_data; int ret; -if (avctx->active_thre
[FFmpeg-devel] [PATCH v1] avformat/dashdec: remove xmlCleanupParser call in dashdec
Because there have global varible in libxml2, it cleans up memory allocated by the library itself. It is a cleanup function for the XML library. It tries to reclaim all related global memory allocated for the library processing. It doesn't deallocate any document related memory. One should call xmlCleanupParser() only when the process has finished using the library and all XML/HTML documents built with it. See also xmlInitParser() which has the opposite function of preparing the library for operations. if there are multithreaded or has plugin support calling this may crash the application if another thread or a plugin is still using libxml2. So give a warning message to user for call xmlCleanupParser by themselves. Signed-off-by: Steven Liu --- libavformat/dashdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 99ac6197be..c33ddb9ea4 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -1362,7 +1362,6 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) cleanup: /*free the document */ xmlFreeDoc(doc); -xmlCleanupParser(); xmlFreeNode(mpd_baseurl_node); } @@ -2026,6 +2025,7 @@ static int dash_read_header(AVFormatContext *s) if ((ret = ffio_copy_url_options(s->pb, &c->avio_opts)) < 0) return ret; +av_log(s, AV_LOG_WARNING, "Have not call xmlCleanupParser yet, you should call it by yourself\n"); if ((ret = parse_manifest(s, s->url, s->pb)) < 0) return ret; -- 2.39.3 (Apple Git-146) ___ 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 3/5] avcodec/ffv1dec: Fix end computation with ec=2
Sponsored-by: Sovereign Tech Fund Signed-off-by: Michael Niedermayer --- libavcodec/ffv1dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index b4d719a7eec..6aa36716cb3 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -347,7 +347,7 @@ static int decode_slice(AVCodecContext *c, void *arg) if (f->ac != AC_GOLOMB_RICE && f->version > 2) { int v; get_rac(&sc->c, (uint8_t[]) { 129 }); -v = sc->c.bytestream_end - sc->c.bytestream - 2 - 5*f->ec; +v = sc->c.bytestream_end - sc->c.bytestream - 2 - 5*!!f->ec; if (v) { av_log(f->avctx, AV_LOG_ERROR, "bytestream end mismatching by %d\n", v); slice_set_damaged(f, sc); -- 2.47.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".
[FFmpeg-devel] [PATCH 5/5] [RFC] libavcodec/ffv1enc: Support storing LSB raw
This makes a 16bit RGB raw sample 25% faster at a 2% loss of compression with rawlsb=4 Please test and comment, especially if you are an archivist caring about compression and speed Id like to know if this is a direction (that is trading compression against speed) that is wanted Note, this only implements the encoder side, you cannot decode this ATM, its only for testing compression and speed Signed-off-by: Michael Niedermayer --- libavcodec/ffv1.h | 1 + libavcodec/ffv1enc.c | 135 +++--- libavcodec/ffv1enc_template.c | 8 ++ 3 files changed, 134 insertions(+), 10 deletions(-) diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h index b98f0b36855..0a8790fdb1b 100644 --- a/libavcodec/ffv1.h +++ b/libavcodec/ffv1.h @@ -136,6 +136,7 @@ typedef struct FFV1Context { int intra; int key_frame_ok; int context_model; +int rawlsb; int bits_per_raw_sample; int packed_at_lsb; diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 30d8073c8d4..ef139d0f4e7 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -290,17 +290,17 @@ static int encode_plane(FFV1Context *f, FFV1SliceContext *sc, sample[1][ w]= sample[1][w-1]; if (f->bits_per_raw_sample <= 8) { for (x = 0; x < w; x++) -sample[0][x] = src[x * pixel_stride + stride * y]; +sample[0][x] = src[x * pixel_stride + stride * y] >> f->rawlsb; if((ret = encode_line(f, sc, f->avctx, w, sample, plane_index, 8, ac, pass1)) < 0) return ret; } else { if (f->packed_at_lsb) { for (x = 0; x < w; x++) { -sample[0][x] = ((uint16_t*)(src + stride*y))[x]; +sample[0][x] = ((uint16_t*)(src + stride*y))[x] >> f->rawlsb; } } else { for (x = 0; x < w; x++) { -sample[0][x] = ((uint16_t*)(src + stride*y))[x] >> (16 - f->bits_per_raw_sample); +sample[0][x] = ((uint16_t*)(src + stride*y))[x] >> (16 - f->bits_per_raw_sample + f->rawlsb); } } if((ret = encode_line(f, sc, f->avctx, w, sample, plane_index, f->bits_per_raw_sample, ac, pass1)) < 0) @@ -310,6 +310,82 @@ static int encode_plane(FFV1Context *f, FFV1SliceContext *sc, return 0; } +static int encode_plane_rawlsb(FFV1Context *f, FFV1SliceContext *sc, +const uint8_t *src, int w, int h, +int stride, int plane_index, int pixel_stride) +{ +int x, y; +unsigned masklsb = (1 << f->rawlsb) - 1; +PutBitContext *pb = &sc->pb; + +for (y = 0; y < h; y++) { +if (f->bits_per_raw_sample <= 8) { +for (x = 0; x < w; x++) +put_bits(pb, f->rawlsb, src[x * pixel_stride + stride * y] & masklsb); +} else { +if (f->packed_at_lsb) { +for (x = 0; x < w; x++) +put_bits(pb, f->rawlsb, ((uint16_t*)(src + stride*y))[x] & masklsb); +} else { +for (x = 0; x < w; x++) +put_bits(pb, f->rawlsb, (((uint16_t*)(src + stride*y))[x] >> (16 - f->bits_per_raw_sample)) & masklsb); +} +} +} +return 0; +} + +static int encode_rgb_frame_rawlsb(FFV1Context *f, FFV1SliceContext *sc, +const uint8_t *src[4], +int w, int h, const int stride[4]) +{ +unsigned masklsb = (1 << f->rawlsb) - 1; +PutBitContext *pb = &sc->pb; +int x, y; +int lbd= f->bits_per_raw_sample <= 8; +int packed = !src[1]; +int transparency = f->transparency; +int packed_size = (3 + transparency)*2; + +for (y = 0; y < h; y++) { +for (x = 0; x < w; x++) { +int b, g, r, av_uninit(a); +if (lbd) { +unsigned v = *((const uint32_t*)(src[0] + x*4 + stride[0]*y)); +b = v& 0xFF; +g = (v >> 8) & 0xFF; +r = (v >> 16) & 0xFF; +a = v >> 24; +} else if (packed) { +const uint16_t *p = ((const uint16_t*)(src[0] + x*packed_size + stride[0]*y)); +r = p[0]; +g = p[1]; +b = p[2]; +if (transparency) + a = p[3]; +} else if (sizeof(TYPE) == 4 || transparency) { +g = *((const uint16_t *)(src[0] + x*2 + stride[0]*y)); +b = *((const uint16_t *)(src[1] + x*2 + stride[1]*y)); +r = *((const uint16_t *)(src[2] + x*2 + stride[2]*y)); +if (transparency) +a = *((const uint16_t *)(src[3] + x*2 + stride[3]*y)); +} else { +b = *((const uint16_t *)(src[0] + x*2 + stride[0]*y)); +g = *((const uint16_t *)(src[1] + x*2 + stride[1]
[FFmpeg-devel] [PATCH 2/5] avcodec/ffv1enc: Move slice termination into threads
Sponsored-by: Sovereign Tech Fund Signed-off-by: Michael Niedermayer --- libavcodec/ffv1enc.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 430e2161a3b..3a431f41365 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -1105,6 +1105,13 @@ retry: ret = encode_rgb_frame(f, sc, planes, width, height, p->linesize); } +if (f->ac != AC_GOLOMB_RICE) { +sc->ac_byte_count = ff_rac_terminate(&sc->c, 1); +} else { +flush_put_bits(&sc->pb); // FIXME: nicer padding +sc->ac_byte_count += put_bytes_output(&sc->pb); +} + if (ret < 0) { av_assert0(sc->slice_coding_mode == 0); if (f->version < 4 || !f->ac) { @@ -1229,14 +1236,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, buf_p = pkt->data; for (i = 0; i < f->slice_count; i++) { FFV1SliceContext *sc = &f->slices[i]; -int bytes; - -if (f->ac != AC_GOLOMB_RICE) { -bytes = ff_rac_terminate(&sc->c, 1); -} else { -flush_put_bits(&sc->pb); // FIXME: nicer padding -bytes = sc->ac_byte_count + put_bytes_output(&sc->pb); -} +int bytes = sc->ac_byte_count; if (i > 0 || f->version > 2) { av_assert0(bytes < pkt->size / f->slice_count); memmove(buf_p, sc->c.bytestream_start, bytes); -- 2.47.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".
[FFmpeg-devel] [PATCH 1/5] avcodec/ffv1enc: allow manually specifying the crc type
Sponsored-by: Sovereign Tech Fund Signed-off-by: Michael Niedermayer --- libavcodec/ffv1enc.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index b9ee5b629a2..430e2161a3b 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -559,8 +559,10 @@ static av_cold int encode_init(AVCodecContext *avctx) } // CRC requires version 3+ -if (s->ec) +if (s->ec == 1) s->version = FFMAX(s->version, 3); +if (s->ec == 2) +s->version = FFMAX(s->version, 4); if ((s->version == 2 || s->version>3) && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { av_log(avctx, AV_LOG_ERROR, "Version 2 or 4 needed for requested features but version 2 or 4 is experimental and not enabled\n"); @@ -1266,7 +1268,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, #define OFFSET(x) offsetof(FFV1Context, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { -{ "slicecrc", "Protect slices with CRCs", OFFSET(ec), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE }, +{ "slicecrc", "Protect slices with CRCs", OFFSET(ec), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 2, VE }, { "coder", "Coder type", OFFSET(ac), AV_OPT_TYPE_INT, { .i64 = 0 }, -2, 2, VE, .unit = "coder" }, { "rice", "Golomb rice", 0, AV_OPT_TYPE_CONST, -- 2.47.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".
[FFmpeg-devel] [PATCH 4/5] avcodec/ffv1enc: Fix RCT with RGB64
Sponsored-by: Sovereign Tech Fund Signed-off-by: Michael Niedermayer --- libavcodec/ffv1enc.c | 8 1 file changed, 8 insertions(+) diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 3a431f41365..30d8073c8d4 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -988,6 +988,9 @@ static void choose_rct_params(const FFV1Context *f, FFV1SliceContext *sc, int x, y, i, p, best; int16_t *sample[3]; int lbd = f->bits_per_raw_sample <= 8; +int packed = !src[1]; +int transparency = f->transparency; +int packed_size = (3 + transparency)*2; for (y = 0; y < h; y++) { int lastr=0, lastg=0, lastb=0; @@ -1002,6 +1005,11 @@ static void choose_rct_params(const FFV1Context *f, FFV1SliceContext *sc, b = v& 0xFF; g = (v >> 8) & 0xFF; r = (v >> 16) & 0xFF; +} else if (packed) { +const uint16_t *p = ((const uint16_t*)(src[0] + x*packed_size + stride[0]*y)); +r = p[0]; +g = p[1]; +b = p[2]; } else { b = *((const uint16_t*)(src[0] + x*2 + stride[0]*y)); g = *((const uint16_t*)(src[1] + x*2 + stride[1]*y)); -- 2.47.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".
Re: [FFmpeg-devel] [PATCH 01/21] swscale/input: add AYUV input support
On Thu, Oct 10, 2024 at 01:45:58PM -0300, James Almer wrote: > On 10/8/2024 7:50 PM, James Almer wrote: > > Signed-off-by: James Almer > > --- > > libswscale/input.c | 35 +++ > > libswscale/utils.c | 1 + > > 2 files changed, 36 insertions(+) > > Will apply patches 5 to 21 soon. please wait 24-48h so i can test and look at them thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Rewriting code that is poorly written but fully understood is good. Rewriting code that one doesnt understand is a sign that one is less smart than the original author, trying to rewrite it will not make it better. 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] ffmpeg-patchwork & trac are down/offline
Hello there, Several domains are down/offline, including: 1. https://patchwork.ffmpeg.org/ 2. FFmpeg trac https://trac.ffmpeg.org/ It seems to be very intermittent at the moment. ___ 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".