[FFmpeg-devel] Add LSX optimization in avcodec and swscale.
v1: Add LSX optimization in avcodec and swscale, due to the 2K series CPUs only support lsx. v2: Modified the implementation of some functions and added support for the checkasm --bench feature. [PATCH v2 1/7] avcodec/la: add LSX optimization for h264 idct. [PATCH v2 2/7] avcodec/la: Add LSX optimization for loop filter. [PATCH v2 3/7] avcodec/la: Add LSX optimization for h264 chroma and [PATCH v2 4/7] avcodec/la: Add LSX optimization for h264 qpel. [PATCH v2 5/7] swscale/la: Optimize the functions of the swscale. [PATCH v2 6/7] swscale/la: Add following builtin optimized functions. [PATCH v2 7/7] avutil/la: Add function performance testing. ___ 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 v2 1/7] avcodec/la: add LSX optimization for h264 idct.
From: Shiyou Yin loongson_asm.S is LoongArch asm optimization helper. Add functions: ff_h264_idct_add_8_lsx ff_h264_idct8_add_8_lsx ff_h264_idct_dc_add_8_lsx ff_h264_idct8_dc_add_8_lsx ff_h264_idct_add16_8_lsx ff_h264_idct8_add4_8_lsx ff_h264_idct_add8_8_lsx ff_h264_idct_add8_422_8_lsx ff_h264_idct_add16_intra_8_lsx ff_h264_luma_dc_dequant_idct_8_lsx Replaced function(LSX is sufficient for these functions): ff_h264_idct_add_lasx ff_h264_idct4x4_addblk_dc_lasx ff_h264_idct_add16_lasx ff_h264_idct8_add4_lasx ff_h264_idct_add8_lasx ff_h264_idct_add8_422_lasx ff_h264_idct_add16_intra_lasx ff_h264_deq_idct_luma_dc_lasx Renamed functions: ff_h264_idct8_addblk_lasx ==> ff_h264_idct8_add_8_lasx ff_h264_idct8_dc_addblk_lasx ==> ff_h264_idct8_dc_add_8_lasx ./configure --disable-lasx ffmpeg -i 1_h264_1080p_30fps_3Mbps.mp4 -f rawvideo -y /dev/null -an before: 155fps after: 161fps --- libavcodec/loongarch/Makefile | 3 +- libavcodec/loongarch/h264_deblock_lasx.c | 2 +- libavcodec/loongarch/h264dsp_init_loongarch.c | 39 +- libavcodec/loongarch/h264dsp_lasx.c | 2 +- .../{h264dsp_lasx.h => h264dsp_loongarch.h} | 60 +- libavcodec/loongarch/h264idct.S | 659 libavcodec/loongarch/h264idct_lasx.c | 498 - libavcodec/loongarch/h264idct_loongarch.c | 185 libavcodec/loongarch/loongson_asm.S | 946 ++ 9 files changed, 1851 insertions(+), 543 deletions(-) rename libavcodec/loongarch/{h264dsp_lasx.h => h264dsp_loongarch.h} (68%) create mode 100644 libavcodec/loongarch/h264idct.S delete mode 100644 libavcodec/loongarch/h264idct_lasx.c create mode 100644 libavcodec/loongarch/h264idct_loongarch.c create mode 100644 libavcodec/loongarch/loongson_asm.S diff --git a/libavcodec/loongarch/Makefile b/libavcodec/loongarch/Makefile index c1b5de5c44..34ebbbe133 100644 --- a/libavcodec/loongarch/Makefile +++ b/libavcodec/loongarch/Makefile @@ -12,7 +12,6 @@ OBJS-$(CONFIG_HEVC_DECODER) += loongarch/hevcdsp_init_loongarch.o LASX-OBJS-$(CONFIG_H264CHROMA)+= loongarch/h264chroma_lasx.o LASX-OBJS-$(CONFIG_H264QPEL) += loongarch/h264qpel_lasx.o LASX-OBJS-$(CONFIG_H264DSP) += loongarch/h264dsp_lasx.o \ - loongarch/h264idct_lasx.o \ loongarch/h264_deblock_lasx.o LASX-OBJS-$(CONFIG_H264PRED) += loongarch/h264_intrapred_lasx.o LASX-OBJS-$(CONFIG_VC1_DECODER) += loongarch/vc1dsp_lasx.o @@ -31,3 +30,5 @@ LSX-OBJS-$(CONFIG_HEVC_DECODER) += loongarch/hevcdsp_lsx.o \ loongarch/hevc_mc_bi_lsx.o \ loongarch/hevc_mc_uni_lsx.o \ loongarch/hevc_mc_uniw_lsx.o +LSX-OBJS-$(CONFIG_H264DSP)+= loongarch/h264idct.o \ + loongarch/h264idct_loongarch.o diff --git a/libavcodec/loongarch/h264_deblock_lasx.c b/libavcodec/loongarch/h264_deblock_lasx.c index c89bea9a84..eead931dcf 100644 --- a/libavcodec/loongarch/h264_deblock_lasx.c +++ b/libavcodec/loongarch/h264_deblock_lasx.c @@ -20,7 +20,7 @@ */ #include "libavcodec/bit_depth_template.c" -#include "h264dsp_lasx.h" +#include "h264dsp_loongarch.h" #include "libavutil/loongarch/loongson_intrinsics.h" #define H264_LOOP_FILTER_STRENGTH_ITERATION_LASX(edges, step, mask_mv, dir, \ diff --git a/libavcodec/loongarch/h264dsp_init_loongarch.c b/libavcodec/loongarch/h264dsp_init_loongarch.c index 37633c3e51..cb07deb398 100644 --- a/libavcodec/loongarch/h264dsp_init_loongarch.c +++ b/libavcodec/loongarch/h264dsp_init_loongarch.c @@ -21,13 +21,32 @@ */ #include "libavutil/loongarch/cpu.h" -#include "h264dsp_lasx.h" +#include "h264dsp_loongarch.h" av_cold void ff_h264dsp_init_loongarch(H264DSPContext *c, const int bit_depth, const int chroma_format_idc) { int cpu_flags = av_get_cpu_flags(); +if (have_lsx(cpu_flags)) { +if (bit_depth == 8) { +c->h264_idct_add = ff_h264_idct_add_8_lsx; +c->h264_idct8_add= ff_h264_idct8_add_8_lsx; +c->h264_idct_dc_add = ff_h264_idct_dc_add_8_lsx; +c->h264_idct8_dc_add = ff_h264_idct8_dc_add_8_lsx; + +if (chroma_format_idc <= 1) +c->h264_idct_add8 = ff_h264_idct_add8_8_lsx; +else +c->h264_idct_add8 = ff_h264_idct_add8_422_8_lsx; + +c->h264_idct_add16 = ff_h264_idct_add16_8_lsx; +c->h264_idct8_add4 = ff_h264_idct8_add4_8_lsx; +c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_8_lsx; +c->h264_idct_add16intra = ff_h264_idct_add16_intra_8_lsx; +} +} +#if HAVE_LASX if (have_lasx(cpu_flags)) { if (chroma_format_idc <= 1) c->h264_loop_filter
[FFmpeg-devel] [PATCH v2 3/7] avcodec/la: Add LSX optimization for h264 chroma and intrapred.
From: Lu Wang ./configure --disable-lasx ffmpeg -i 1_h264_1080p_30fps_3Mbps.mp4 -f rawvideo -y /dev/null -an before: 199fps after: 214fps --- libavcodec/loongarch/Makefile |4 +- .../loongarch/h264_intrapred_init_loongarch.c | 18 +- libavcodec/loongarch/h264_intrapred_lasx.c| 121 -- ...pred_lasx.h => h264_intrapred_loongarch.h} | 12 +- libavcodec/loongarch/h264chroma.S | 966 + .../loongarch/h264chroma_init_loongarch.c | 10 +- libavcodec/loongarch/h264chroma_lasx.c| 1280 - libavcodec/loongarch/h264chroma_lasx.h| 36 - libavcodec/loongarch/h264chroma_loongarch.h | 41 + libavcodec/loongarch/h264intrapred.S | 299 10 files changed, 1342 insertions(+), 1445 deletions(-) delete mode 100644 libavcodec/loongarch/h264_intrapred_lasx.c rename libavcodec/loongarch/{h264_intrapred_lasx.h => h264_intrapred_loongarch.h} (70%) create mode 100644 libavcodec/loongarch/h264chroma.S delete mode 100644 libavcodec/loongarch/h264chroma_lasx.c delete mode 100644 libavcodec/loongarch/h264chroma_lasx.h create mode 100644 libavcodec/loongarch/h264chroma_loongarch.h create mode 100644 libavcodec/loongarch/h264intrapred.S diff --git a/libavcodec/loongarch/Makefile b/libavcodec/loongarch/Makefile index 111bc23e4e..a563055161 100644 --- a/libavcodec/loongarch/Makefile +++ b/libavcodec/loongarch/Makefile @@ -9,11 +9,9 @@ OBJS-$(CONFIG_HPELDSP)+= loongarch/hpeldsp_init_loongarch.o OBJS-$(CONFIG_IDCTDSP)+= loongarch/idctdsp_init_loongarch.o OBJS-$(CONFIG_VIDEODSP) += loongarch/videodsp_init.o OBJS-$(CONFIG_HEVC_DECODER) += loongarch/hevcdsp_init_loongarch.o -LASX-OBJS-$(CONFIG_H264CHROMA)+= loongarch/h264chroma_lasx.o LASX-OBJS-$(CONFIG_H264QPEL) += loongarch/h264qpel_lasx.o LASX-OBJS-$(CONFIG_H264DSP) += loongarch/h264dsp_lasx.o \ loongarch/h264_deblock_lasx.o -LASX-OBJS-$(CONFIG_H264PRED) += loongarch/h264_intrapred_lasx.o LASX-OBJS-$(CONFIG_VC1_DECODER) += loongarch/vc1dsp_lasx.o LASX-OBJS-$(CONFIG_HPELDSP) += loongarch/hpeldsp_lasx.o LASX-OBJS-$(CONFIG_IDCTDSP) += loongarch/simple_idct_lasx.o \ @@ -33,3 +31,5 @@ LSX-OBJS-$(CONFIG_HEVC_DECODER) += loongarch/hevcdsp_lsx.o \ LSX-OBJS-$(CONFIG_H264DSP)+= loongarch/h264idct.o \ loongarch/h264idct_loongarch.o \ loongarch/h264dsp.o +LSX-OBJS-$(CONFIG_H264CHROMA) += loongarch/h264chroma.o +LSX-OBJS-$(CONFIG_H264PRED) += loongarch/h264intrapred.o diff --git a/libavcodec/loongarch/h264_intrapred_init_loongarch.c b/libavcodec/loongarch/h264_intrapred_init_loongarch.c index 12620bd842..c415fa30da 100644 --- a/libavcodec/loongarch/h264_intrapred_init_loongarch.c +++ b/libavcodec/loongarch/h264_intrapred_init_loongarch.c @@ -21,7 +21,7 @@ #include "libavutil/loongarch/cpu.h" #include "libavcodec/h264pred.h" -#include "h264_intrapred_lasx.h" +#include "h264_intrapred_loongarch.h" av_cold void ff_h264_pred_init_loongarch(H264PredContext *h, int codec_id, const int bit_depth, @@ -30,6 +30,22 @@ av_cold void ff_h264_pred_init_loongarch(H264PredContext *h, int codec_id, int cpu_flags = av_get_cpu_flags(); if (bit_depth == 8) { +if (have_lsx(cpu_flags)) { +if (chroma_format_idc <= 1) { +} +if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) { +} else { +if (chroma_format_idc <= 1) { +} +if (codec_id == AV_CODEC_ID_SVQ3) { +h->pred16x16[PLANE_PRED8x8] = ff_h264_pred16x16_plane_svq3_8_lsx; +} else if (codec_id == AV_CODEC_ID_RV40) { +h->pred16x16[PLANE_PRED8x8] = ff_h264_pred16x16_plane_rv40_8_lsx; +} else { +h->pred16x16[PLANE_PRED8x8] = ff_h264_pred16x16_plane_h264_8_lsx; +} +} +} if (have_lasx(cpu_flags)) { if (chroma_format_idc <= 1) { } diff --git a/libavcodec/loongarch/h264_intrapred_lasx.c b/libavcodec/loongarch/h264_intrapred_lasx.c deleted file mode 100644 index c38cd611b8..00 --- a/libavcodec/loongarch/h264_intrapred_lasx.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2021 Loongson Technology Corporation Limited - * Contributed by Hao Chen - * - * 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 WARR
[FFmpeg-devel] [PATCH v2 4/7] avcodec/la: Add LSX optimization for h264 qpel.
From: yuanhecai ./configure --disable-lasx ffmpeg -i 1_h264_1080p_30fps_3Mbps.mp4 -f rawvideo -y /dev/null -an before: 214fps after: 274fps --- libavcodec/loongarch/Makefile |2 + libavcodec/loongarch/h264qpel.S | 1686 + .../loongarch/h264qpel_init_loongarch.c | 74 +- libavcodec/loongarch/h264qpel_lasx.c | 401 +--- libavcodec/loongarch/h264qpel_lasx.h | 158 -- libavcodec/loongarch/h264qpel_loongarch.h | 312 +++ libavcodec/loongarch/h264qpel_lsx.c | 488 + 7 files changed, 2562 insertions(+), 559 deletions(-) create mode 100644 libavcodec/loongarch/h264qpel.S delete mode 100644 libavcodec/loongarch/h264qpel_lasx.h create mode 100644 libavcodec/loongarch/h264qpel_loongarch.h create mode 100644 libavcodec/loongarch/h264qpel_lsx.c diff --git a/libavcodec/loongarch/Makefile b/libavcodec/loongarch/Makefile index a563055161..06cfab5c20 100644 --- a/libavcodec/loongarch/Makefile +++ b/libavcodec/loongarch/Makefile @@ -31,5 +31,7 @@ LSX-OBJS-$(CONFIG_HEVC_DECODER) += loongarch/hevcdsp_lsx.o \ LSX-OBJS-$(CONFIG_H264DSP)+= loongarch/h264idct.o \ loongarch/h264idct_loongarch.o \ loongarch/h264dsp.o +LSX-OBJS-$(CONFIG_H264QPEL) += loongarch/h264qpel.o \ + loongarch/h264qpel_lsx.o LSX-OBJS-$(CONFIG_H264CHROMA) += loongarch/h264chroma.o LSX-OBJS-$(CONFIG_H264PRED) += loongarch/h264intrapred.o diff --git a/libavcodec/loongarch/h264qpel.S b/libavcodec/loongarch/h264qpel.S new file mode 100644 index 00..3f885b6ce2 --- /dev/null +++ b/libavcodec/loongarch/h264qpel.S @@ -0,0 +1,1686 @@ +/* + * Loongson LSX optimized h264qpel + * + * Copyright (c) 2023 Loongson Technology Corporation Limited + * Contributed by Hecai Yuan + * + * 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 "loongson_asm.S" + +.macro VLD_QPEL8_H_SSRANI_LSX in0, in1, in2, in3, in4 +vld vr0,\in4, 0 +vldx vr1,\in4, a2 +QPEL8_H_LSX \in0, \in1 +vssrani.bu.h \in0, \in2, 5 +vssrani.bu.h \in1, \in3, 5 +.endm + +.macro VLDX_QPEL8_H_SSRANI_LSX in0, in1, in2, in3, in4 +vldx vr0,\in4, t1 +vldx vr1,\in4, t2 +QPEL8_H_LSX \in0, \in1 +vssrani.bu.h \in0, \in2, 5 +vssrani.bu.h \in1, \in3, 5 +.endm + +.macro VLD_DOUBLE_QPEL8_H_SSRANI_LSX in0, in1, in2, in3, in4, in5, in6, in7, in8 +vld vr0,\in8, 0 +vldx vr1,\in8, a2 +QPEL8_H_LSX \in0, \in1 +vssrani.bu.h \in0, \in4, 5 +vssrani.bu.h \in1, \in5, 5 +vldx vr0,\in8, t1 +vldx vr1,\in8, t2 +QPEL8_H_LSX \in2, \in3 +vssrani.bu.h \in2, \in6, 5 +vssrani.bu.h \in3, \in7, 5 +.endm + +function ff_put_h264_qpel16_mc00_lsx +slli.dt0, a2, 1 +add.d t1, t0, a2 +slli.dt2, t0, 1 +.rept 4 +vld vr0,a1, 0 +vldx vr1,a1, a2 +vldx vr2,a1, t0 +vldx vr3,a1, t1 +add.d a1, a1, t2 +vst vr0,a0, 0 +vstx vr1,a0, a2 +vstx vr2,a0, t0 +vstx vr3,a0, t1 +add.d a0, a0, t2 +.endr +endfunc + +.macro QPEL8_H_LSX out0, out1 +vbsrl.v vr2,vr0,1 +vbsrl.v vr3,vr1,1 +vbsrl.v vr4,vr0,2 +vbsrl.v vr5,vr1,2 +vbsrl.v vr6,vr0,3 +vbsrl.v vr7,vr1,3 +vbsrl.v vr8,vr0,4 +vbsrl.v vr9,vr1,4 +vbsrl.v vr10, vr0,5 +vbsrl.v vr11, vr1,5 + +vilvl.b vr6,vr4,vr6 +vilvl.b vr7,vr5,vr7 +vilvl.b vr8,vr2,vr8 +vilvl.b vr9,vr3,vr9 +vilvl.b vr10, vr0,vr10 +vilvl.b vr11, vr1,vr11 +vhaddw.hu.bu vr6,vr6,vr6 +vhaddw.hu.bu vr7,vr7,vr7 +vhaddw.hu.bu vr8,vr8,vr8 +vh
[FFmpeg-devel] [PATCH v2 6/7] swscale/la: Add following builtin optimized functions
From: Jin Bo yuv420_rgb24_lsx yuv420_bgr24_lsx yuv420_rgba32_lsx yuv420_argb32_lsx yuv420_bgra32_lsx yuv420_abgr32_lsx ./configure --disable-lasx ffmpeg -i ~/media/1_h264_1080p_30fps_3Mbps.mp4 -f rawvideo -pix_fmt rgb24 -y /dev/null -an before: 184fps after: 207fps --- libswscale/loongarch/Makefile | 3 +- libswscale/loongarch/swscale_init_loongarch.c | 30 +- libswscale/loongarch/swscale_loongarch.h | 18 + libswscale/loongarch/yuv2rgb_lsx.c| 361 ++ 4 files changed, 410 insertions(+), 2 deletions(-) create mode 100644 libswscale/loongarch/yuv2rgb_lsx.c diff --git a/libswscale/loongarch/Makefile b/libswscale/loongarch/Makefile index c0b6a449c0..c35ba309a4 100644 --- a/libswscale/loongarch/Makefile +++ b/libswscale/loongarch/Makefile @@ -8,4 +8,5 @@ LSX-OBJS-$(CONFIG_SWSCALE) += loongarch/swscale.o \ loongarch/swscale_lsx.o \ loongarch/input.o \ loongarch/output.o \ - loongarch/output_lsx.o + loongarch/output_lsx.o \ + loongarch/yuv2rgb_lsx.o diff --git a/libswscale/loongarch/swscale_init_loongarch.c b/libswscale/loongarch/swscale_init_loongarch.c index c13a1662ec..53e4f970b6 100644 --- a/libswscale/loongarch/swscale_init_loongarch.c +++ b/libswscale/loongarch/swscale_init_loongarch.c @@ -90,8 +90,8 @@ av_cold void rgb2rgb_init_loongarch(void) av_cold SwsFunc ff_yuv2rgb_init_loongarch(SwsContext *c) { -#if HAVE_LASX int cpu_flags = av_get_cpu_flags(); +#if HAVE_LASX if (have_lasx(cpu_flags)) { switch (c->dstFormat) { case AV_PIX_FMT_RGB24: @@ -121,5 +121,33 @@ av_cold SwsFunc ff_yuv2rgb_init_loongarch(SwsContext *c) } } #endif // #if HAVE_LASX +if (have_lsx(cpu_flags)) { +switch (c->dstFormat) { +case AV_PIX_FMT_RGB24: +return yuv420_rgb24_lsx; +case AV_PIX_FMT_BGR24: +return yuv420_bgr24_lsx; +case AV_PIX_FMT_RGBA: +if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) { +break; +} else +return yuv420_rgba32_lsx; +case AV_PIX_FMT_ARGB: +if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) { +break; +} else +return yuv420_argb32_lsx; +case AV_PIX_FMT_BGRA: +if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) { +break; +} else +return yuv420_bgra32_lsx; +case AV_PIX_FMT_ABGR: +if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) { +break; +} else +return yuv420_abgr32_lsx; +} +} return NULL; } diff --git a/libswscale/loongarch/swscale_loongarch.h b/libswscale/loongarch/swscale_loongarch.h index bc29913ac6..0514abae21 100644 --- a/libswscale/loongarch/swscale_loongarch.h +++ b/libswscale/loongarch/swscale_loongarch.h @@ -62,6 +62,24 @@ void ff_yuv2planeX_8_lsx(const int16_t *filter, int filterSize, av_cold void ff_sws_init_output_lsx(SwsContext *c); +int yuv420_rgb24_lsx(SwsContext *c, const uint8_t *src[], int srcStride[], + int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[]); + +int yuv420_bgr24_lsx(SwsContext *c, const uint8_t *src[], int srcStride[], + int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[]); + +int yuv420_rgba32_lsx(SwsContext *c, const uint8_t *src[], int srcStride[], + int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[]); + +int yuv420_bgra32_lsx(SwsContext *c, const uint8_t *src[], int srcStride[], + int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[]); + +int yuv420_argb32_lsx(SwsContext *c, const uint8_t *src[], int srcStride[], + int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[]); + +int yuv420_abgr32_lsx(SwsContext *c, const uint8_t *src[], int srcStride[], + int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[]); + #if HAVE_LASX void ff_hscale_8_to_15_lasx(SwsContext *c, int16_t *dst, int dstW, const uint8_t *src, const int16_t *filter, diff --git a/libswscale/loongarch/yuv2rgb_lsx.c b/libswscale/loongarch/yuv2rgb_lsx.c new file mode 100644 index 00..11cd2f79d9 --- /dev/null +++ b/libswscale/loongarch/yuv2rgb_lsx.c @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2023 Loongson Technology Co. Ltd. + * Contributed by Bo Jin(ji...@loongson.cn) + * All rights reserved. + * + * 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 th
[FFmpeg-devel] [PATCH v2] avutil/la: Add function performance testing
From: yuanhecai This patch supports the use of the "checkasm --bench" testing feature on loongarch platform. Change-Id: I42790388d057c9ade0dfa38a19d9c1fd44ca0bc3 --- libavutil/loongarch/timer.h | 48 + libavutil/timer.h | 2 ++ 2 files changed, 50 insertions(+) create mode 100644 libavutil/loongarch/timer.h diff --git a/libavutil/loongarch/timer.h b/libavutil/loongarch/timer.h new file mode 100644 index 00..44ed786409 --- /dev/null +++ b/libavutil/loongarch/timer.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Loongson Technology Corporation Limited + * Contributed by Hecai Yuan + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LOONGARCH_TIMER_H +#define AVUTIL_LOONGARCH_TIMER_H + +#include +#include "config.h" + +#if HAVE_INLINE_ASM + +#define AV_READ_TIME read_time + +static inline uint64_t read_time(void) +{ + +#if ARCH_LOONGARCH64 +uint64_t a, id = 0; +__asm__ volatile ( "rdtime.d %0, %1" : "=r"(a), "=r"(id) :: "memory" ); +return a; +#else +uint32_t a, id = 0; +__asm__ volatile ( "rdtimel.w %0, %1" : "=r"(a), "=r"(id) :: "memory" ); +return (uint64_t)a; +#endif +} + +#endif /* HAVE_INLINE_ASM */ + +#endif /* AVUTIL_LOONGARCH_TIMER_H */ diff --git a/libavutil/timer.h b/libavutil/timer.h index d3db5a27ef..861ba7e9d7 100644 --- a/libavutil/timer.h +++ b/libavutil/timer.h @@ -61,6 +61,8 @@ # include "riscv/timer.h" #elif ARCH_X86 # include "x86/timer.h" +#elif ARCH_LOONGARCH +# include "loongarch/timer.h" #endif #if !defined(AV_READ_TIME) -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] lavc/h264chroma: RISC-V V add motion compensation for 8x8 chroma blocks
Optimize the put and avg filtering for 8x8 chroma blocks Signed-off-by: Arnie Chang --- libavcodec/h264chroma.c | 2 + libavcodec/h264chroma.h | 1 + libavcodec/riscv/Makefile | 3 + libavcodec/riscv/h264_chroma_init_riscv.c | 39 ++ libavcodec/riscv/h264_mc_chroma.S | 492 ++ libavcodec/riscv/h264_mc_chroma.h | 34 ++ 6 files changed, 571 insertions(+) create mode 100644 libavcodec/riscv/h264_chroma_init_riscv.c create mode 100644 libavcodec/riscv/h264_mc_chroma.S create mode 100644 libavcodec/riscv/h264_mc_chroma.h diff --git a/libavcodec/h264chroma.c b/libavcodec/h264chroma.c index 60b86b6fba..1eeab7bc40 100644 --- a/libavcodec/h264chroma.c +++ b/libavcodec/h264chroma.c @@ -58,5 +58,7 @@ av_cold void ff_h264chroma_init(H264ChromaContext *c, int bit_depth) ff_h264chroma_init_mips(c, bit_depth); #elif ARCH_LOONGARCH64 ff_h264chroma_init_loongarch(c, bit_depth); +#elif ARCH_RISCV +ff_h264chroma_init_riscv(c, bit_depth); #endif } diff --git a/libavcodec/h264chroma.h b/libavcodec/h264chroma.h index b8f9c8f4fc..9c81c18a76 100644 --- a/libavcodec/h264chroma.h +++ b/libavcodec/h264chroma.h @@ -37,5 +37,6 @@ void ff_h264chroma_init_ppc(H264ChromaContext *c, int bit_depth); void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth); void ff_h264chroma_init_mips(H264ChromaContext *c, int bit_depth); void ff_h264chroma_init_loongarch(H264ChromaContext *c, int bit_depth); +void ff_h264chroma_init_riscv(H264ChromaContext *c, int bit_depth); #endif /* AVCODEC_H264CHROMA_H */ diff --git a/libavcodec/riscv/Makefile b/libavcodec/riscv/Makefile index 965942f4df..08b76c93cb 100644 --- a/libavcodec/riscv/Makefile +++ b/libavcodec/riscv/Makefile @@ -19,3 +19,6 @@ OBJS-$(CONFIG_PIXBLOCKDSP) += riscv/pixblockdsp_init.o \ RVV-OBJS-$(CONFIG_PIXBLOCKDSP) += riscv/pixblockdsp_rvv.o OBJS-$(CONFIG_VORBIS_DECODER) += riscv/vorbisdsp_init.o RVV-OBJS-$(CONFIG_VORBIS_DECODER) += riscv/vorbisdsp_rvv.o + +OBJS-$(CONFIG_H264CHROMA) += riscv/h264_chroma_init_riscv.o +RVV-OBJS-$(CONFIG_H264CHROMA) += riscv/h264_mc_chroma.o diff --git a/libavcodec/riscv/h264_chroma_init_riscv.c b/libavcodec/riscv/h264_chroma_init_riscv.c new file mode 100644 index 00..b6f98ba693 --- /dev/null +++ b/libavcodec/riscv/h264_chroma_init_riscv.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 SiFive, Inc. All rights reserved. + * + * 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 + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavcodec/h264chroma.h" +#include "config.h" +#include "h264_mc_chroma.h" + +av_cold void ff_h264chroma_init_riscv(H264ChromaContext *c, int bit_depth) +{ +#if HAVE_RVV +const int high_bit_depth = bit_depth > 8; + +if (!high_bit_depth) { +c->put_h264_chroma_pixels_tab[0] = h264_put_chroma_mc8_rvv; +c->avg_h264_chroma_pixels_tab[0] = h264_avg_chroma_mc8_rvv; +} +#endif +} \ No newline at end of file diff --git a/libavcodec/riscv/h264_mc_chroma.S b/libavcodec/riscv/h264_mc_chroma.S new file mode 100644 index 00..a02866f633 --- /dev/null +++ b/libavcodec/riscv/h264_mc_chroma.S @@ -0,0 +1,492 @@ +/* + * Copyright (c) 2023 SiFive, Inc. All rights reserved. + * + * 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 + */ +.text + +.globlh264_put_chroma_mc8_rvv +.p2align1 +.typeh264_put_chroma_mc8_rvv,@function +h264_put_chroma_mc8_rvv: +slliwt2, a5, 3 +mulwt1, a5, a4 +sh3a
Re: [FFmpeg-devel] [PATCH v2 1/7] avcodec/la: add LSX optimization for h264 idct.
> 2023年5月17日 15:03,Hao Chen 写道: > > From: Shiyou Yin > > loongson_asm.S is LoongArch asm optimization helper. > Add functions: > ff_h264_idct_add_8_lsx > ff_h264_idct8_add_8_lsx > ff_h264_idct_dc_add_8_lsx > ff_h264_idct8_dc_add_8_lsx > ff_h264_idct_add16_8_lsx > ff_h264_idct8_add4_8_lsx > ff_h264_idct_add8_8_lsx > ff_h264_idct_add8_422_8_lsx > ff_h264_idct_add16_intra_8_lsx > ff_h264_luma_dc_dequant_idct_8_lsx > Replaced function(LSX is sufficient for these functions): > ff_h264_idct_add_lasx > ff_h264_idct4x4_addblk_dc_lasx > ff_h264_idct_add16_lasx > ff_h264_idct8_add4_lasx > ff_h264_idct_add8_lasx > ff_h264_idct_add8_422_lasx > ff_h264_idct_add16_intra_lasx > ff_h264_deq_idct_luma_dc_lasx > Renamed functions: > ff_h264_idct8_addblk_lasx ==> ff_h264_idct8_add_8_lasx > ff_h264_idct8_dc_addblk_lasx ==> ff_h264_idct8_dc_add_8_lasx > > ./configure --disable-lasx > ffmpeg -i 1_h264_1080p_30fps_3Mbps.mp4 -f rawvideo -y /dev/null -an > before: 155fps > after: 161fps > --- > libavcodec/loongarch/Makefile | 3 +- > libavcodec/loongarch/h264_deblock_lasx.c | 2 +- > libavcodec/loongarch/h264dsp_init_loongarch.c | 39 +- > libavcodec/loongarch/h264dsp_lasx.c | 2 +- > .../{h264dsp_lasx.h => h264dsp_loongarch.h} | 60 +- > libavcodec/loongarch/h264idct.S | 659 > libavcodec/loongarch/h264idct_lasx.c | 498 - > libavcodec/loongarch/h264idct_loongarch.c | 185 > libavcodec/loongarch/loongson_asm.S | 946 ++ > 9 files changed, 1851 insertions(+), 543 deletions(-) > rename libavcodec/loongarch/{h264dsp_lasx.h => h264dsp_loongarch.h} (68%) > create mode 100644 libavcodec/loongarch/h264idct.S > delete mode 100644 libavcodec/loongarch/h264idct_lasx.c > create mode 100644 libavcodec/loongarch/h264idct_loongarch.c > create mode 100644 libavcodec/loongarch/loongson_asm.S > LGTM ___ 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] Add LSX optimization in avcodec and swscale.
> 2023年5月17日 15:03,Hao Chen 写道: > > v1: Add LSX optimization in avcodec and swscale, due to the 2K series CPUs > only support lsx. > v2: Modified the implementation of some functions and added support for the > checkasm --bench feature. > > [PATCH v2 1/7] avcodec/la: add LSX optimization for h264 idct. > [PATCH v2 2/7] avcodec/la: Add LSX optimization for loop filter. > [PATCH v2 3/7] avcodec/la: Add LSX optimization for h264 chroma and > [PATCH v2 4/7] avcodec/la: Add LSX optimization for h264 qpel. > [PATCH v2 5/7] swscale/la: Optimize the functions of the swscale. > [PATCH v2 6/7] swscale/la: Add following builtin optimized functions. > [PATCH v2 7/7] avutil/la: Add function performance testing. > > ___ > LGTM ___ 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 v6] avformat: add MMTP parser and MMT/TLV demuxer
Bumping this, thx. On Wed, May 3, 2023 at 22:02 SuperFashi wrote: > v1 -> v2: Refactor using GetByteContext; Fix compile error. > v2 -> v3: Remove debug statement. > v3 -> v4: Squash commits. > v4 -> v5: Improve portability; Cosmetic changes. > v5 -> v6: remove unnecessary NULL checks. > > This patch adds an MPEG Media Transport Protocol (MMTP) parser, as defined > in ISO/IEC 23008-1, and an MMT protocol over TLV packets (MMT/TLV) demuxer, > as defined in ARIB STD-B32. Currently, it supports HEVC, AAC LATM, and > ARIB-TTML demuxing. > > Since MMTP is designed to transmit over IP, there is no size information > within each MMTP packet, and there is no on-disk format defined alongside > the protocol. One industrial solution is a simple container format using > type–length–value packets, which is defined in ARIB STD-B32. > > Another known container format for MMTP is using packet capture (pcap) > files which records network packets. This patch does not include the > demuxer for this container format. > > Signed-off-by: SuperFashi > --- > Changelog|1 + > doc/demuxers.texi|4 + > libavformat/Makefile |1 + > libavformat/allformats.c |1 + > libavformat/mmtp.c | 1525 ++ > libavformat/mmtp.h | 64 ++ > libavformat/mmttlv.c | 335 + > libavformat/version.h|2 +- > 8 files changed, 1932 insertions(+), 1 deletion(-) > create mode 100644 libavformat/mmtp.c > create mode 100644 libavformat/mmtp.h > create mode 100644 libavformat/mmttlv.c > > diff --git a/Changelog b/Changelog > index 4901ef6ad7..594c445ea2 100644 > --- a/Changelog > +++ b/Changelog > @@ -7,6 +7,7 @@ version : > - Extend VAAPI support for libva-win32 on Windows > - afireqsrc audio source filter > - arls filter > +- MMTP parser and MMT/TLV demuxer > > version 6.0: > - Radiance HDR image support > diff --git a/doc/demuxers.texi b/doc/demuxers.texi > index 2d33b47a56..56aab251b2 100644 > --- a/doc/demuxers.texi > +++ b/doc/demuxers.texi > @@ -689,6 +689,10 @@ Set the sample rate for libopenmpt to output. > Range is from 1000 to INT_MAX. The value default is 48000. > @end table > > +@section mmttlv > + > +Demuxer for MMT protocol over TLV packets (MMT/TLV), as defined in ARIB > STD-B32. > + > @section mov/mp4/3gp > > Demuxer for Quicktime File Format & ISO/IEC Base Media File Format > (ISO/IEC 14496-12 or MPEG-4 Part 12, ISO/IEC 15444-12 or JPEG 2000 Part 12). > diff --git a/libavformat/Makefile b/libavformat/Makefile > index f8ad7c6a11..e32d6e71a3 100644 > --- a/libavformat/Makefile > +++ b/libavformat/Makefile > @@ -354,6 +354,7 @@ OBJS-$(CONFIG_MLV_DEMUXER) += mlvdec.o > riffdec.o > OBJS-$(CONFIG_MM_DEMUXER)+= mm.o > OBJS-$(CONFIG_MMF_DEMUXER) += mmf.o > OBJS-$(CONFIG_MMF_MUXER) += mmf.o rawenc.o > +OBJS-$(CONFIG_MMTTLV_DEMUXER)+= mmtp.o mmttlv.o > OBJS-$(CONFIG_MODS_DEMUXER) += mods.o > OBJS-$(CONFIG_MOFLEX_DEMUXER)+= moflex.o > OBJS-$(CONFIG_MOV_DEMUXER) += mov.o mov_chan.o mov_esds.o \ > diff --git a/libavformat/allformats.c b/libavformat/allformats.c > index efdb34e29d..d5f4f5680e 100644 > --- a/libavformat/allformats.c > +++ b/libavformat/allformats.c > @@ -270,6 +270,7 @@ extern const AVInputFormat ff_mlv_demuxer; > extern const AVInputFormat ff_mm_demuxer; > extern const AVInputFormat ff_mmf_demuxer; > extern const FFOutputFormat ff_mmf_muxer; > +extern const AVInputFormat ff_mmttlv_demuxer; > extern const AVInputFormat ff_mods_demuxer; > extern const AVInputFormat ff_moflex_demuxer; > extern const AVInputFormat ff_mov_demuxer; > diff --git a/libavformat/mmtp.c b/libavformat/mmtp.c > new file mode 100644 > index 00..6f002cc827 > --- /dev/null > +++ b/libavformat/mmtp.c > @@ -0,0 +1,1525 @@ > +/* > + * MPEG Media Transport Protocol (MMTP) parser, as defined in ISO/IEC > 23008-1. > + * Copyright (c) 2023 SuperFashi > + * > + * 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 > + > +#include "libavcodec/bytestream.h" > +#include "libavutil/avassert.h" > +#include "libavutil/intreadwrite.h" > +#include "libavutil/mem.h" > +#in
Re: [FFmpeg-devel] [PATCH v2] avcodec/mediacodec: Add VP8 encoder
Thanks. Somehow messed up the patch file sent in the email. -Original Message- From: ffmpeg-devel On Behalf Of "zhilizhao(???)" Sent: keskiviikko 17. toukokuuta 2023 6.39 To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [PATCH v2] avcodec/mediacodec: Add VP8 encoder Failed to build since missing +DECLARE_MEDIACODEC_ENCODER(vp8, "VP8", AV_CODEC_ID_VP8) Fixed locally and pushed as 416fd1b. > On May 17, 2023, at 01:34, Samuel Raposo Vieira Mira > wrote: > > > > <0001-avcodec-mediacodec-Add-VP8-encoder.patch.b64><0001-avcodec-media > codec-Add-VP8-encoder.patch>__ > _ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 02/36] fftools/ffmpeg: drop a useless local variable
Store decoded frame timestamp directly in AVFrame.pts, there is no advantage to using a separate local variable for it. --- fftools/ffmpeg.c | 18 +- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 084192f270..60f0ff3b12 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -1029,7 +1029,6 @@ static int decode_video(InputStream *ist, const AVPacket *pkt, int *got_output, { AVFrame *frame = ist->decoded_frame; int ret = 0, err = 0; -int64_t best_effort_timestamp; // With fate-indeo3-2, we're getting 0-sized packets before EOF for some // reason. This seems like a semi-critical bug. Don't trigger EOF, and @@ -1089,19 +1088,15 @@ static int decode_video(InputStream *ist, const AVPacket *pkt, int *got_output, goto fail; } -best_effort_timestamp = frame->best_effort_timestamp; +frame->pts = frame->best_effort_timestamp; if (ist->framerate.num) -best_effort_timestamp = ist->cfr_next_pts++; +frame->pts = ist->cfr_next_pts++; // no timestamp available - extrapolate from previous frame duration -if (best_effort_timestamp == AV_NOPTS_VALUE) -best_effort_timestamp = ist->last_frame_pts == AV_NOPTS_VALUE ? 0 : -ist->last_frame_pts + ist->last_frame_duration_est; - -if(best_effort_timestamp != AV_NOPTS_VALUE) { -frame->pts = best_effort_timestamp; -} +if (frame->pts == AV_NOPTS_VALUE) +frame->pts = ist->last_frame_pts == AV_NOPTS_VALUE ? 0 : + ist->last_frame_pts + ist->last_frame_duration_est; // update timestamp history ist->last_frame_duration_est = video_duration_estimate(ist, frame); @@ -1112,15 +1107,12 @@ static int decode_video(InputStream *ist, const AVPacket *pkt, int *got_output, av_log(ist, AV_LOG_INFO, "decoder -> pts:%s pts_time:%s " "pkt_dts:%s pkt_dts_time:%s " - "best_effort_ts:%"PRId64" best_effort_ts_time:%s " "duration:%s duration_time:%s " "keyframe:%d frame_type:%d time_base:%d/%d\n", av_ts2str(frame->pts), av_ts2timestr(frame->pts, &ist->st->time_base), av_ts2str(frame->pkt_dts), av_ts2timestr(frame->pkt_dts, &ist->st->time_base), - best_effort_timestamp, - av_ts2timestr(best_effort_timestamp, &ist->st->time_base), av_ts2str(frame->duration), av_ts2timestr(frame->duration, &ist->st->time_base), !!(frame->flags & AV_FRAME_FLAG_KEY), frame->pict_type, -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 06/36] fftools/ffmpeg: rework applying input -r
Do not use a separate counter for CFR timestamps forced with -r used as an input option. Set durations properly and let estimation code do the rest. --- fftools/ffmpeg.c | 10 +++--- fftools/ffmpeg.h | 4 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 9e5e56e9e7..e368f5a148 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -985,7 +985,7 @@ static int64_t video_duration_estimate(const InputStream *ist, const AVFrame *fr // durations, then this should be simplified. // prefer frame duration for containers with timestamps -if (frame->duration > 0 && !ifile->format_nots) +if (frame->duration > 0 && (!ifile->format_nots || ist->framerate.num)) return frame->duration; if (ist->dec_ctx->framerate.den && ist->dec_ctx->framerate.num) { @@ -1090,8 +1090,12 @@ static int decode_video(InputStream *ist, const AVPacket *pkt, int *got_output, frame->pts = frame->best_effort_timestamp; -if (ist->framerate.num) -frame->pts = ist->cfr_next_pts++; +// forced fixed framerate +if (ist->framerate.num) { +frame->pts = AV_NOPTS_VALUE; +frame->duration = 1; +frame->time_base = av_inv_q(ist->framerate); +} // no timestamp available - extrapolate from previous frame duration if (frame->pts == AV_NOPTS_VALUE) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index f88792d7eb..3c7991c73a 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -372,10 +372,6 @@ typedef struct InputStream { int64_t filter_in_rescale_delta_last; -// when forcing constant input framerate through -r, -// this contains the pts that will be given to the next decoded frame -int64_t cfr_next_pts; - int64_t nb_samples; /* number of samples in the last decoded audio frame before looping */ AVDictionary *decoder_opts; -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 03/36] fftools/ffmpeg: replace stream timebase with decoded frame one
They are the same for now, but this may change in the future. --- fftools/ffmpeg.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 60f0ff3b12..9e5e56e9e7 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -993,7 +993,7 @@ static int64_t video_duration_estimate(const InputStream *ist, const AVFrame *fr AVRational field_rate = av_mul_q(ist->dec_ctx->framerate, (AVRational){ 2, 1 }); codec_duration = av_rescale_q(fields, av_inv_q(field_rate), - ist->st->time_base); + frame->time_base); } // prefer codec-layer duration for containers without timestamps @@ -1015,7 +1015,7 @@ static int64_t video_duration_estimate(const InputStream *ist, const AVFrame *fr // try average framerate if (ist->st->avg_frame_rate.num && ist->st->avg_frame_rate.den) { int64_t d = av_rescale_q(1, av_inv_q(ist->st->avg_frame_rate), - ist->st->time_base); + frame->time_base); if (d > 0) return d; } @@ -1110,13 +1110,13 @@ static int decode_video(InputStream *ist, const AVPacket *pkt, int *got_output, "duration:%s duration_time:%s " "keyframe:%d frame_type:%d time_base:%d/%d\n", av_ts2str(frame->pts), - av_ts2timestr(frame->pts, &ist->st->time_base), + av_ts2timestr(frame->pts, &frame->time_base), av_ts2str(frame->pkt_dts), - av_ts2timestr(frame->pkt_dts, &ist->st->time_base), + av_ts2timestr(frame->pkt_dts, &frame->time_base), av_ts2str(frame->duration), - av_ts2timestr(frame->duration, &ist->st->time_base), + av_ts2timestr(frame->duration, &frame->time_base), !!(frame->flags & AV_FRAME_FLAG_KEY), frame->pict_type, - ist->st->time_base.num, ist->st->time_base.den); + frame->time_base.num, frame->time_base.den); } if (ist->st->sample_aspect_ratio.num) -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 01/36] fftools/ffmpeg: shorten a variable name
There is only one frame used in decode_video() -- the one output by the decoder. So there is no point in explicitly calling it the _decoded_ frame. --- fftools/ffmpeg.c | 52 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index ebd793a98c..084192f270 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -1027,7 +1027,7 @@ static int64_t video_duration_estimate(const InputStream *ist, const AVFrame *fr static int decode_video(InputStream *ist, const AVPacket *pkt, int *got_output, int eof, int *decode_failed) { -AVFrame *decoded_frame = ist->decoded_frame; +AVFrame *frame = ist->decoded_frame; int ret = 0, err = 0; int64_t best_effort_timestamp; @@ -1038,7 +1038,7 @@ static int decode_video(InputStream *ist, const AVPacket *pkt, int *got_output, return 0; update_benchmark(NULL); -ret = decode(ist, ist->dec_ctx, decoded_frame, got_output, pkt); +ret = decode(ist, ist->dec_ctx, frame, got_output, pkt); update_benchmark("decode_video %d.%d", ist->file_index, ist->st->index); if (ret < 0) *decode_failed = 1; @@ -1062,13 +1062,13 @@ static int decode_video(InputStream *ist, const AVPacket *pkt, int *got_output, check_decode_result(ist, got_output, ret); if (*got_output && ret >= 0) { -if (ist->dec_ctx->width != decoded_frame->width || -ist->dec_ctx->height != decoded_frame->height || -ist->dec_ctx->pix_fmt != decoded_frame->format) { +if (ist->dec_ctx->width != frame->width || +ist->dec_ctx->height != frame->height || +ist->dec_ctx->pix_fmt != frame->format) { av_log(NULL, AV_LOG_DEBUG, "Frame parameters mismatch context %d,%d,%d != %d,%d,%d\n", -decoded_frame->width, -decoded_frame->height, -decoded_frame->format, +frame->width, +frame->height, +frame->format, ist->dec_ctx->width, ist->dec_ctx->height, ist->dec_ctx->pix_fmt); @@ -1079,17 +1079,17 @@ static int decode_video(InputStream *ist, const AVPacket *pkt, int *got_output, return ret; if(ist->top_field_first>=0) -decoded_frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; +frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; ist->frames_decoded++; -if (ist->hwaccel_retrieve_data && decoded_frame->format == ist->hwaccel_pix_fmt) { -err = ist->hwaccel_retrieve_data(ist->dec_ctx, decoded_frame); +if (ist->hwaccel_retrieve_data && frame->format == ist->hwaccel_pix_fmt) { +err = ist->hwaccel_retrieve_data(ist->dec_ctx, frame); if (err < 0) goto fail; } -best_effort_timestamp= decoded_frame->best_effort_timestamp; +best_effort_timestamp = frame->best_effort_timestamp; if (ist->framerate.num) best_effort_timestamp = ist->cfr_next_pts++; @@ -1100,13 +1100,13 @@ static int decode_video(InputStream *ist, const AVPacket *pkt, int *got_output, ist->last_frame_pts + ist->last_frame_duration_est; if(best_effort_timestamp != AV_NOPTS_VALUE) { -decoded_frame->pts = best_effort_timestamp; +frame->pts = best_effort_timestamp; } // update timestamp history -ist->last_frame_duration_est = video_duration_estimate(ist, decoded_frame); -ist->last_frame_pts = decoded_frame->pts; -ist->last_frame_tb = decoded_frame->time_base; +ist->last_frame_duration_est = video_duration_estimate(ist, frame); +ist->last_frame_pts = frame->pts; +ist->last_frame_tb = frame->time_base; if (debug_ts) { av_log(ist, AV_LOG_INFO, @@ -1115,25 +1115,25 @@ static int decode_video(InputStream *ist, const AVPacket *pkt, int *got_output, "best_effort_ts:%"PRId64" best_effort_ts_time:%s " "duration:%s duration_time:%s " "keyframe:%d frame_type:%d time_base:%d/%d\n", - av_ts2str(decoded_frame->pts), - av_ts2timestr(decoded_frame->pts, &ist->st->time_base), - av_ts2str(decoded_frame->pkt_dts), - av_ts2timestr(decoded_frame->pkt_dts, &ist->st->time_base), + av_ts2str(frame->pts), + av_ts2timestr(frame->pts, &ist->st->time_base), + av_ts2str(frame->pkt_dts), + av_ts2timestr(frame->pkt_dts, &ist->st->time_base), best_effort_timestamp, av_ts2timestr(best_effort_timestamp, &ist->st->time_base), - av_ts2str(decoded_frame->duration), - av_ts2timestr(decoded_frame->duration, &ist->st->time_base), - !!(decoded_frame->flags & AV_FRAME_FLAG_KEY), decoded_frame->pict_type, + av_ts2str(frame->d
[FFmpeg-devel] [PATCH 04/36] fftools/ffmpeg_filter: convert input frame timestamps
Decoder timebase does not always have to match filter timebase. --- fftools/ffmpeg_filter.c | 29 - 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index aea951a2da..95ffa0f087 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -55,6 +55,9 @@ static FilterGraphPriv *fgp_from_fg(FilterGraph *fg) typedef struct InputFilterPriv { InputFilter ifilter; +// used to hold submitted input +AVFrame *frame; + int eof; AVRational time_base; @@ -244,6 +247,10 @@ static InputFilter *ifilter_alloc(FilterGraph *fg) ifilter->graph = fg; ifilter->format = -1; +ifp->frame = av_frame_alloc(); +if (!ifp->frame) +report_and_exit(AVERROR(ENOMEM)); + ifp->fallback.format = -1; ifp->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW); @@ -284,6 +291,8 @@ void fg_free(FilterGraph **pfg) av_channel_layout_uninit(&ifp->fallback.ch_layout); +av_frame_free(&ifp->frame); + av_buffer_unref(&ifp->hw_frames_ctx); av_freep(&ifilter->name); av_freep(&fg->inputs[j]); @@ -1541,10 +1550,6 @@ int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference) FilterGraph *fg = ifilter->graph; AVFrameSideData *sd; int need_reinit, ret; -int buffersrc_flags = AV_BUFFERSRC_FLAG_PUSH; - -if (keep_reference) -buffersrc_flags |= AV_BUFFERSRC_FLAG_KEEP_REF; /* determine if the parameters for this input changed */ need_reinit = ifilter->format != frame->format; @@ -1606,8 +1611,22 @@ int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference) } } -ret = av_buffersrc_add_frame_flags(ifilter->filter, frame, buffersrc_flags); +if (keep_reference) { +ret = av_frame_ref(ifp->frame, frame); +if (ret < 0) +return ret; +} else +av_frame_move_ref(ifp->frame, frame); +frame = ifp->frame; + +frame->pts = av_rescale_q(frame->pts, frame->time_base, ifp->time_base); +frame->duration = av_rescale_q(frame->duration, frame->time_base, ifp->time_base); +frame->time_base = ifp->time_base; + +ret = av_buffersrc_add_frame_flags(ifilter->filter, frame, + AV_BUFFERSRC_FLAG_PUSH); if (ret < 0) { +av_frame_unref(frame); if (ret != AVERROR_EOF) av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret)); return ret; -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 08/36] tests/fate/ffmpeg: add a test for input -r option
--- tests/fate/ffmpeg.mak | 4 tests/ref/fate/ffmpeg-input-r | 12 2 files changed, 16 insertions(+) create mode 100644 tests/ref/fate/ffmpeg-input-r diff --git a/tests/fate/ffmpeg.mak b/tests/fate/ffmpeg.mak index 892624e523..aca949176a 100644 --- a/tests/fate/ffmpeg.mak +++ b/tests/fate/ffmpeg.mak @@ -223,3 +223,7 @@ FATE_TIME_BASE-$(call PARSERDEMDEC, MPEGVIDEO, MPEGPS, MPEG2VIDEO, MPEGVIDEO_DEM fate-time_base: CMD = md5 -i $(TARGET_SAMPLES)/mpeg2/dvd_single_frame.vob -an -sn -c:v copy -r 25 -time_base 1001:3 -fflags +bitexact -f mxf FATE_SAMPLES_FFMPEG-yes += $(FATE_TIME_BASE-yes) + +# test -r used as an input option +fate-ffmpeg-input-r: CMD = framecrc -r 27 -i $(TARGET_SAMPLES)/mpeg2/sony-ct3.bs +FATE_SAMPLES_FFMPEG-$(call FRAMECRC, MPEGVIDEO, MPEG2VIDEO) += fate-ffmpeg-input-r diff --git a/tests/ref/fate/ffmpeg-input-r b/tests/ref/fate/ffmpeg-input-r new file mode 100644 index 00..d11f870b10 --- /dev/null +++ b/tests/ref/fate/ffmpeg-input-r @@ -0,0 +1,12 @@ +#tb 0: 1/27 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 720x480 +#sar 0: 8/9 +0, 0, 0,1, 518400, 0xc1866f5f +0, 1, 1,1, 518400, 0x9ba32764 +0, 2, 2,1, 518400, 0xa9031bb8 +0, 3, 3,1, 518400, 0x5e2c3502 +0, 4, 4,1, 518400, 0xe860027a +0, 5, 5,1, 518400, 0xa9152430 +0, 6, 6,1, 518400, 0xb98dd9f7 -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 13/36] fftools/ffmpeg_filter: try configuring graphs from input EOF
When a filtergraph input receives EOF but never saw any input frames, we use the fallback parameters. Currently an attempt to actually configure the filtergraph will happen elsewhere, but there is no reason to postpone this. --- fftools/ffmpeg_filter.c | 8 1 file changed, 8 insertions(+) diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 8eca0f2cae..6323278d15 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -1533,6 +1533,14 @@ int ifilter_send_eof(InputFilter *ifilter, int64_t pts, AVRational tb) &ifp->fallback.ch_layout); if (ret < 0) return ret; + +if (ifilter_has_all_input_formats(ifilter->graph)) { +ret = configure_filtergraph(ifilter->graph); +if (ret < 0) { +av_log(NULL, AV_LOG_ERROR, "Error initializing filters!\n"); +return ret; +} +} } if (ifilter->format < 0 && (ifilter->type == AVMEDIA_TYPE_AUDIO || ifilter->type == AVMEDIA_TYPE_VIDEO)) { -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 28/36] fftools/ffmpeg: split decoding loop out of process_input_packet()
process_input_packet() contains two non-interacting pieces of nontrivial size and complexity - decoding and streamcopy. Separating them makes the code easier to read. --- fftools/ffmpeg.c | 37 - 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 4cf8b54dc0..e84add50e5 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -1344,18 +1344,10 @@ static int send_filter_eof(InputStream *ist) return 0; } -/* pkt = NULL means EOF (needed to flush decoder buffers) */ -static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eof) +static int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof) { -InputFile *f = input_files[ist->file_index]; -const AVCodecParameters *par = ist->par; -int64_t dts_est = AV_NOPTS_VALUE; -int ret = 0; -int repeating = 0; -int eof_reached = 0; -int duration_exceeded; - AVPacket *avpkt = ist->pkt; +int ret, repeating = 0; if (pkt) { av_packet_unref(avpkt); @@ -1365,11 +1357,11 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo } // while we have more to decode or while the decoder did output something on EOF -while (ist->decoding_needed) { +while (1) { int got_output = 0; int decode_failed = 0; -switch (par->codec_type) { +switch (ist->par->codec_type) { case AVMEDIA_TYPE_AUDIO: ret = decode_audio(ist, repeating ? NULL : avpkt, &got_output, &decode_failed); @@ -1403,8 +1395,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo } } -eof_reached = 1; -break; +return AVERROR_EOF; } if (ret < 0) { @@ -1417,16 +1408,28 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo } if (!decode_failed || exit_on_error) exit_program(1); -break; +return ret; } if (!got_output) -break; +return 0; repeating = 1; } +} + +/* pkt = NULL means EOF (needed to flush decoder buffers) */ +static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eof) +{ +InputFile *f = input_files[ist->file_index]; +int64_t dts_est = AV_NOPTS_VALUE; +int ret = 0; +int eof_reached = 0; +int duration_exceeded; -if (!pkt && !ist->decoding_needed) +if (ist->decoding_needed) +ret = dec_packet(ist, pkt, no_eof); +if (ret == AVERROR_EOF || (!pkt && !ist->decoding_needed)) eof_reached = 1; if (pkt && pkt->opaque_ref) { -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 21/36] fftools/cmdutils: constify the argument of get_rotation()
--- fftools/cmdutils.c | 2 +- fftools/cmdutils.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c index a1de621d1c..9ec00add30 100644 --- a/fftools/cmdutils.c +++ b/fftools/cmdutils.c @@ -994,7 +994,7 @@ void *allocate_array_elem(void *ptr, size_t elem_size, int *nb_elems) return new_elem; } -double get_rotation(int32_t *displaymatrix) +double get_rotation(const int32_t *displaymatrix) { double theta = 0; if (displaymatrix) diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h index 4496221983..0115940225 100644 --- a/fftools/cmdutils.h +++ b/fftools/cmdutils.h @@ -461,6 +461,6 @@ void *allocate_array_elem(void *array, size_t elem_size, int *nb_elems); char name[16];\ snprintf(name, sizeof(name), "%d", rate); -double get_rotation(int32_t *displaymatrix); +double get_rotation(const int32_t *displaymatrix); #endif /* FFTOOLS_CMDUTILS_H */ -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 11/36] fftools/ffmpeg_demux: disallow using disabled input streams
This is less ad-hoc than checking explicitly in every place that binds an input stream to a filter or output. --- fftools/ffmpeg_demux.c | 6 ++ fftools/ffmpeg_filter.c | 5 - 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index ae2133bdbf..df87e0f30a 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -848,6 +848,12 @@ static int ist_use(InputStream *ist, int decoding_needed) { DemuxStream *ds = ds_from_ist(ist); +if (ist->user_set_discard == AVDISCARD_ALL) { +av_log(ist, AV_LOG_ERROR, "Cannot %s a disabled input stream\n", + decoding_needed ? "decode" : "streamcopy"); +return AVERROR(EINVAL); +} + ist->discard = 0; ist->st->discard = ist->user_set_discard; ist->decoding_needed |= decoding_needed; diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index ca43b4803a..2c3e2a96f7 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -417,11 +417,6 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) exit_program(1); } ist = input_files[file_idx]->streams[st->index]; -if (ist->user_set_discard == AVDISCARD_ALL) { -av_log(NULL, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s " - "matches a disabled input stream.\n", p, fgp->graph_desc); -exit_program(1); -} } else { ist = ist_find_unused(type); if (!ist) { -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 09/36] fftools/ffmpeg_filter: split finding an unused stream into a function
Avoids filtering code from digging in demuxer internals. --- fftools/ffmpeg.h| 5 + fftools/ffmpeg_demux.c | 10 ++ fftools/ffmpeg_filter.c | 8 +--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 3c7991c73a..9cb7198dfd 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -882,6 +882,11 @@ int ifile_get_packet(InputFile *f, AVPacket **pkt); void ist_output_add(InputStream *ist, OutputStream *ost); void ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple); +/** + * Find an unused input stream of given type. + */ +InputStream *ist_find_unused(enum AVMediaType type); + /* iterate over all input streams in all input files; * pass NULL to start iteration */ InputStream *ist_iter(InputStream *prev); diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index 0a37cc7c25..b93e171037 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -130,6 +130,16 @@ static Demuxer *demuxer_from_ifile(InputFile *f) return (Demuxer*)f; } +InputStream *ist_find_unused(enum AVMediaType type) +{ +for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) { +if (ist->par->codec_type == type && ist->discard && +ist->user_set_discard != AVDISCARD_ALL) +return ist; +} +return NULL; +} + static void report_new_stream(Demuxer *d, const AVPacket *pkt) { AVStream *st = d->f.ctx->streams[pkt->stream_index]; diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 274eefe11c..8cc76209d0 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -420,13 +420,7 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) exit_program(1); } } else { -/* find the first unused stream of corresponding type */ -for (ist = ist_iter(NULL); ist; ist = ist_iter(ist)) { -if (ist->user_set_discard == AVDISCARD_ALL) -continue; -if (ist->dec_ctx->codec_type == type && ist->discard) -break; -} +ist = ist_find_unused(type); if (!ist) { av_log(NULL, AV_LOG_FATAL, "Cannot find a matching stream for " "unlabeled input pad %d on filter %s\n", in->pad_idx, -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 10/36] fftools/ffmpeg: return error codes from ist_*_add()
Will be useful in future commits. --- fftools/ffmpeg.h | 4 ++-- fftools/ffmpeg_demux.c| 26 +++--- fftools/ffmpeg_filter.c | 15 --- fftools/ffmpeg_mux_init.c | 10 -- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 9cb7198dfd..189454d629 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -879,8 +879,8 @@ void ifile_close(InputFile **f); */ int ifile_get_packet(InputFile *f, AVPacket **pkt); -void ist_output_add(InputStream *ist, OutputStream *ost); -void ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple); +int ist_output_add(InputStream *ist, OutputStream *ost); +int ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple); /** * Find an unused input stream of given type. diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index b93e171037..ae2133bdbf 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -844,7 +844,7 @@ void ifile_close(InputFile **pf) av_freep(pf); } -static void ist_use(InputStream *ist, int decoding_needed) +static int ist_use(InputStream *ist, int decoding_needed) { DemuxStream *ds = ds_from_ist(ist); @@ -856,23 +856,33 @@ static void ist_use(InputStream *ist, int decoding_needed) if (decoding_needed && !avcodec_is_open(ist->dec_ctx)) { int ret = dec_open(ist); if (ret < 0) -report_and_exit(ret); +return ret; } + +return 0; } -void ist_output_add(InputStream *ist, OutputStream *ost) +int ist_output_add(InputStream *ist, OutputStream *ost) { -ist_use(ist, ost->enc ? DECODING_FOR_OST : 0); +int ret; + +ret = ist_use(ist, ost->enc ? DECODING_FOR_OST : 0); +if (ret < 0) +return ret; GROW_ARRAY(ist->outputs, ist->nb_outputs); ist->outputs[ist->nb_outputs - 1] = ost; + +return 0; } -void ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple) +int ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple) { int ret; -ist_use(ist, is_simple ? DECODING_FOR_OST : DECODING_FOR_FILTER); +ret = ist_use(ist, is_simple ? DECODING_FOR_OST : DECODING_FOR_FILTER); +if (ret < 0) +return ret; GROW_ARRAY(ist->filters, ist->nb_filters); ist->filters[ist->nb_filters - 1] = ifilter; @@ -880,7 +890,9 @@ void ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple) // initialize fallback parameters for filtering ret = ifilter_parameters_from_dec(ifilter, ist->dec_ctx); if (ret < 0) -report_and_exit(ret); +return ret; + +return 0; } static const AVCodec *choose_decoder(const OptionsContext *o, AVFormatContext *s, AVStream *st, diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 8cc76209d0..ca43b4803a 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -334,6 +334,7 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost) FilterGraph *fg; OutputFilter *ofilter; InputFilter *ifilter; +int ret; fg = fg_create(NULL); if (!fg) @@ -347,7 +348,9 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost) ifilter = ifilter_alloc(fg); ifilter->ist= ist; -ist_filter_add(ist, ifilter, 1); +ret = ist_filter_add(ist, ifilter, 1); +if (ret < 0) +return ret; return 0; } @@ -375,7 +378,7 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) InputStream *ist = NULL; enum AVMediaType type = avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx); InputFilter *ifilter; -int i; +int i, ret; // TODO: support other filter types if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) { @@ -435,7 +438,13 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) ifilter->type = ist->st->codecpar->codec_type; ifilter->name = describe_filter_link(fg, in, 1); -ist_filter_add(ist, ifilter, 0); +ret = ist_filter_add(ist, ifilter, 0); +if (ret < 0) { +av_log(NULL, AV_LOG_ERROR, + "Error binding an input stream to complex filtergraph input %s.\n", + in->name ? in->name : ""); +exit_program(1); +} } static int read_binary(const char *path, uint8_t **data, int *len) diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index 2c0e2faf4a..b73791acee 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -1225,8 +1225,14 @@ static OutputStream *ost_add(Muxer *mux, const OptionsContext *o, "Error initializing a simple filtergraph\n"); exit_program(1); } -} else -ist_output_add(ost->ist, ost); +} else { +ret = ist_output_add(ost->ist, ost); +if (ret < 0) { +av_log(ost, AV_LOG_ERROR, +
[FFmpeg-devel] [PATCH 07/36] tests/fate/ffmpeg: move a misplaced line
--- tests/fate/ffmpeg.mak | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/fate/ffmpeg.mak b/tests/fate/ffmpeg.mak index 0f33c2a0ed..892624e523 100644 --- a/tests/fate/ffmpeg.mak +++ b/tests/fate/ffmpeg.mak @@ -190,6 +190,7 @@ fate-copy-shortest1: CMD = framemd5 -auto_conversion_filters -fflags +bitexact - fate-copy-shortest2: CMD = framemd5 -auto_conversion_filters -fflags +bitexact -flags +bitexact -f lavfi -i "sine=3000:d=10" -i $(TARGET_PATH)/tests/data/audio_shorter_than_video.nut -filter_complex "[0:a:0][1:a:0]amix=inputs=2[audio]" -map 1:v:0 -map "[audio]" -fflags +bitexact -flags +bitexact -c:v copy -c:a ac3_fixed -shortest fate-streamcopy: $(FATE_STREAMCOPY-yes) +FATE_SAMPLES_FFMPEG-yes += $(FATE_STREAMCOPY-yes) FATE_SAMPLES_FFMPEG-$(call TRANSCODE, RAWVIDEO, MATROSKA, MOV_DEMUXER QTRLE_DECODER) += fate-rgb24-mkv fate-rgb24-mkv: CMD = transcode "mov" $(TARGET_SAMPLES)/qtrle/aletrek-rle.mov\ @@ -218,8 +219,6 @@ fate-ffmpeg-bsf-remove-e: CMD = transcode "mpeg" $(TARGET_SAMPLES)/mpeg2/matrixb FATE_SAMPLES_FFMPEG-$(call DEMMUX, APNG, FRAMECRC, SETTS_BSF PIPE_PROTOCOL) += fate-ffmpeg-setts-bsf fate-ffmpeg-setts-bsf: CMD = framecrc -i $(TARGET_SAMPLES)/apng/clock.png -c:v copy -bsf:v "setts=duration=if(eq(NEXT_PTS\,NOPTS)\,PREV_OUTDURATION\,(NEXT_PTS-PTS)/2):ts=PTS/2" -fflags +bitexact -FATE_SAMPLES_FFMPEG-yes += $(FATE_STREAMCOPY-yes) - FATE_TIME_BASE-$(call PARSERDEMDEC, MPEGVIDEO, MPEGPS, MPEG2VIDEO, MPEGVIDEO_DEMUXER MXF_MUXER) += fate-time_base fate-time_base: CMD = md5 -i $(TARGET_SAMPLES)/mpeg2/dvd_single_frame.vob -an -sn -c:v copy -r 25 -time_base 1001:3 -fflags +bitexact -f mxf -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 20/36] fftools/ffmpeg_filter: embed displaymatrix into private context
It has a small fixed size, so it is better to embed it rather than deal with dynamic allocation. --- fftools/ffmpeg_filter.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index c699431831..6f842f6b46 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -83,7 +83,8 @@ typedef struct InputFilterPriv { AVBufferRef *hw_frames_ctx; -int32_t *displaymatrix; +int displaymatrix_present; +int32_t displaymatrix[9]; // fallback parameters to use when no input is ever sent struct { @@ -302,7 +303,6 @@ void fg_free(FilterGraph **pfg) av_frame_free(&frame); av_fifo_freep2(&ifp->frame_queue); } -av_freep(&ifp->displaymatrix); if (ist->sub2video.sub_queue) { AVSubtitle sub; while (av_fifo_read(ist->sub2video.sub_queue, &sub, 1) >= 0) @@ -1094,7 +1094,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, int32_t *displaymatrix = ifp->displaymatrix; double theta; -if (!displaymatrix) +if (!ifp->displaymatrix_present) displaymatrix = (int32_t *)av_stream_get_side_data(ist->st, AV_PKT_DATA_DISPLAYMATRIX, NULL); theta = get_rotation(displaymatrix); @@ -1450,10 +1450,10 @@ static int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *fr if (ret < 0) return ret; -av_freep(&ifp->displaymatrix); sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX); if (sd) -ifp->displaymatrix = av_memdup(sd->data, sizeof(int32_t) * 9); +memcpy(ifp->displaymatrix, sd->data, sizeof(ifp->displaymatrix)); +ifp->displaymatrix_present = !!sd; return 0; } @@ -1611,9 +1611,10 @@ int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference) need_reinit = 1; if (sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX)) { -if (!ifp->displaymatrix || memcmp(sd->data, ifp->displaymatrix, sizeof(int32_t) * 9)) +if (!ifp->displaymatrix_present || +memcmp(sd->data, ifp->displaymatrix, sizeof(ifp->displaymatrix))) need_reinit = 1; -} else if (ifp->displaymatrix) +} else if (ifp->displaymatrix_present) need_reinit = 1; if (need_reinit) { -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 36/36] fftools/ffmpeg_dec: rename decode_video() to video_frame_process()
This function does not do any decoding anymore. --- fftools/ffmpeg_dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c index c8f9ba0f0c..b541d30214 100644 --- a/fftools/ffmpeg_dec.c +++ b/fftools/ffmpeg_dec.c @@ -179,7 +179,7 @@ static int64_t video_duration_estimate(const InputStream *ist, const AVFrame *fr return FFMAX(ist->last_frame_duration_est, 1); } -static int decode_video(InputStream *ist, AVFrame *frame) +static int video_frame_process(InputStream *ist, AVFrame *frame) { // The following line may be required in some cases where there is no parser // or the parser does not has_b_frames correctly @@ -458,7 +458,7 @@ int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof) audio_ts_process(ist, frame); } else { -ret = decode_video(ist, frame); +ret = video_frame_process(ist, frame); if (ret < 0) { av_log(NULL, AV_LOG_FATAL, "Error while processing the decoded " "data for stream #%d:%d\n", ist->file_index, ist->st->index); -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 31/36] fftools/ffmpeg_dec: restructure audio/video decoding loop
It currently emulates the long-removed avcodec_decode_audio4/avcodec_decode_video2 APIs, which obfuscates the actual decoding flow. Restructure the decoding calls so that they naturally follow the new avcodec_send_packet()/avcodec_receive_frame() design. This is not only significantly easier to read, but also shorter. --- fftools/ffmpeg_dec.c | 187 ++- 1 file changed, 61 insertions(+), 126 deletions(-) diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c index 646b587f9e..73f826c76a 100644 --- a/fftools/ffmpeg_dec.c +++ b/fftools/ffmpeg_dec.c @@ -31,7 +31,7 @@ #include "ffmpeg.h" -static void check_decode_result(InputStream *ist, int *got_output, int ret) +static void check_decode_result(InputStream *ist, int got_output, int ret) { if (ret < 0) ist->decode_errors++; @@ -39,7 +39,7 @@ static void check_decode_result(InputStream *ist, int *got_output, int ret) if (ret < 0 && exit_on_error) exit_program(1); -if (*got_output && ist->dec_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE) { +if (got_output && ist->dec_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE) { if (ist->decoded_frame->decode_error_flags || (ist->decoded_frame->flags & AV_FRAME_FLAG_CORRUPT)) { av_log(ist, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING, "corrupt decoded frame\n"); @@ -49,52 +49,6 @@ static void check_decode_result(InputStream *ist, int *got_output, int ret) } } -// This does not quite work like avcodec_decode_audio4/avcodec_decode_video2. -// There is the following difference: if you got a frame, you must call -// it again with pkt=NULL. pkt==NULL is treated differently from pkt->size==0 -// (pkt==NULL means get more output, pkt->size==0 is a flush/drain packet) -static int decode(InputStream *ist, AVCodecContext *avctx, - AVFrame *frame, int *got_frame, const AVPacket *pkt) -{ -int ret; - -*got_frame = 0; - -if (pkt) { -ret = avcodec_send_packet(avctx, pkt); -// In particular, we don't expect AVERROR(EAGAIN), because we read all -// decoded frames with avcodec_receive_frame() until done. -if (ret < 0 && ret != AVERROR_EOF) -return ret; -} - -ret = avcodec_receive_frame(avctx, frame); -if (ret < 0 && ret != AVERROR(EAGAIN)) -return ret; -if (ret >= 0) { -if (ist->want_frame_data) { -FrameData *fd; - -av_assert0(!frame->opaque_ref); -frame->opaque_ref = av_buffer_allocz(sizeof(*fd)); -if (!frame->opaque_ref) { -av_frame_unref(frame); -return AVERROR(ENOMEM); -} -fd = (FrameData*)frame->opaque_ref->data; -fd->pts = frame->pts; -fd->tb = avctx->pkt_timebase; -fd->idx = avctx->frame_num - 1; -} - -frame->time_base = avctx->pkt_timebase; - -*got_frame = 1; -} - -return 0; -} - static int send_frame_to_filters(InputStream *ist, AVFrame *decoded_frame) { int i, ret; @@ -192,25 +146,10 @@ static void audio_ts_process(InputStream *ist, AVFrame *frame) frame->time_base = tb_filter; } -static int decode_audio(InputStream *ist, const AVPacket *pkt, int *got_output, -int *decode_failed) +static int decode_audio(InputStream *ist, AVFrame *decoded_frame) { -AVFrame *decoded_frame = ist->decoded_frame; -AVCodecContext *avctx = ist->dec_ctx; int ret, err = 0; -update_benchmark(NULL); -ret = decode(ist, avctx, decoded_frame, got_output, pkt); -update_benchmark("decode_audio %d.%d", ist->file_index, ist->st->index); -if (ret < 0) -*decode_failed = 1; - -if (ret != AVERROR_EOF) -check_decode_result(ist, got_output, ret); - -if (!*got_output || ret < 0) -return ret; - ist->samples_decoded += decoded_frame->nb_samples; ist->frames_decoded++; @@ -274,24 +213,10 @@ static int64_t video_duration_estimate(const InputStream *ist, const AVFrame *fr return FFMAX(ist->last_frame_duration_est, 1); } -static int decode_video(InputStream *ist, const AVPacket *pkt, int *got_output, -int eof, int *decode_failed) +static int decode_video(InputStream *ist, AVFrame *frame) { -AVFrame *frame = ist->decoded_frame; int ret = 0, err = 0; -// With fate-indeo3-2, we're getting 0-sized packets before EOF for some -// reason. This seems like a semi-critical bug. Don't trigger EOF, and -// skip the packet. -if (!eof && pkt && pkt->size == 0) -return 0; - -update_benchmark(NULL); -ret = decode(ist, ist->dec_ctx, frame, got_output, pkt); -update_benchmark("decode_video %d.%d", ist->file_index, ist->st->index); -if (ret < 0) -*decode_failed = 1; - // The following line may be required in some cases where there is no parser // or the parser does not has_
[FFmpeg-devel] [PATCH 35/36] fftools/ffmpeg_dec: inline decode_audio() into dec_packet()
The former function is now trivial - it has 3 lines and cannot fail. --- fftools/ffmpeg_dec.c | 29 +++-- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c index 4662d0a265..c8f9ba0f0c 100644 --- a/fftools/ffmpeg_dec.c +++ b/fftools/ffmpeg_dec.c @@ -128,17 +128,6 @@ static void audio_ts_process(InputStream *ist, AVFrame *frame) frame->time_base = tb_filter; } -static int decode_audio(InputStream *ist, AVFrame *decoded_frame) -{ -ist->samples_decoded += decoded_frame->nb_samples; - -audio_ts_process(ist, decoded_frame); - -ist->nb_samples = decoded_frame->nb_samples; - -return 0; -} - static int64_t video_duration_estimate(const InputStream *ist, const AVFrame *frame) { const InputFile *ifile = input_files[ist->file_index]; @@ -463,14 +452,18 @@ int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof) frame->time_base = dec->pkt_timebase; -ret = dec->codec_type == AVMEDIA_TYPE_AUDIO ? -decode_audio(ist, frame): -decode_video(ist, frame); +if (dec->codec_type == AVMEDIA_TYPE_AUDIO) { +ist->samples_decoded += frame->nb_samples; +ist->nb_samples = frame->nb_samples; -if (ret < 0) { -av_log(NULL, AV_LOG_FATAL, "Error while processing the decoded " - "data for stream #%d:%d\n", ist->file_index, ist->st->index); -exit_program(1); +audio_ts_process(ist, frame); +} else { +ret = decode_video(ist, frame); +if (ret < 0) { +av_log(NULL, AV_LOG_FATAL, "Error while processing the decoded " + "data for stream #%d:%d\n", ist->file_index, ist->st->index); +exit_program(1); +} } ist->frames_decoded++; -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 18/36] fftools/ffmpeg_filter: move InputFilter.type to private data
It is not accessed outside of ffmpeg_filter. --- fftools/ffmpeg.h| 1 - fftools/ffmpeg_filter.c | 12 +++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index c33e537faa..04c41a5311 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -281,7 +281,6 @@ typedef struct InputFilter { AVFilterContext*filter; struct FilterGraph *graph; uint8_t*name; -enum AVMediaTypetype; // AVMEDIA_TYPE_SUBTITLE for sub2video } InputFilter; typedef struct OutputFilter { diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index e6e9e00985..5656fa87df 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -60,6 +60,9 @@ typedef struct InputFilterPriv { // used to hold submitted input AVFrame *frame; +// AVMEDIA_TYPE_SUBTITLE for sub2video +enum AVMediaType type; + int eof; // parameters configured for this input @@ -264,6 +267,7 @@ static InputFilter *ifilter_alloc(FilterGraph *fg, InputStream *ist) ifp->format = -1; ifp->fallback.format = -1; ifp->ist = ist; +ifp->type= ist->st->codecpar->codec_type; ifp->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW); if (!ifp->frame_queue) @@ -440,8 +444,6 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) av_assert0(ist); ifilter = ifilter_alloc(fg, ist); - -ifilter->type = ist->st->codecpar->codec_type; ifilter->name = describe_filter_link(fg, in, 1); ret = ist_filter_add(ist, ifilter, 0); @@ -1457,8 +1459,8 @@ int ifilter_has_all_input_formats(FilterGraph *fg) int i; for (i = 0; i < fg->nb_inputs; i++) { InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]); -if (ifp->format < 0 && (fg->inputs[i]->type == AVMEDIA_TYPE_AUDIO || -fg->inputs[i]->type == AVMEDIA_TYPE_VIDEO)) +if (ifp->format < 0 && (ifp->type == AVMEDIA_TYPE_AUDIO || +ifp->type == AVMEDIA_TYPE_VIDEO)) return 0; } return 1; @@ -1562,7 +1564,7 @@ int ifilter_send_eof(InputFilter *ifilter, int64_t pts, AVRational tb) } } -if (ifp->format < 0 && (ifilter->type == AVMEDIA_TYPE_AUDIO || ifilter->type == AVMEDIA_TYPE_VIDEO)) { +if (ifp->format < 0 && (ifp->type == AVMEDIA_TYPE_AUDIO || ifp->type == AVMEDIA_TYPE_VIDEO)) { av_log(NULL, AV_LOG_ERROR, "Cannot determine format of input stream %d:%d after EOF\n", ifp->ist->file_index, ifp->ist->st->index); -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 25/36] fftools/ffmpeg: deobfuscate check_decode_result() call
Passing ist=NULL is currently used to identify stream types that do not decode into AVFrames, i.e. subtitles. That is highly non-obvious - always pass a non-NULL InputStream and just check the type explicitly. --- fftools/ffmpeg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 1fcabd123a..537f287637 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -777,7 +777,7 @@ static void check_decode_result(InputStream *ist, int *got_output, int ret) if (ret < 0 && exit_on_error) exit_program(1); -if (*got_output && ist) { +if (*got_output && ist->dec_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE) { if (ist->decoded_frame->decode_error_flags || (ist->decoded_frame->flags & AV_FRAME_FLAG_CORRUPT)) { av_log(ist, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING, "corrupt decoded frame\n"); @@ -1317,7 +1317,7 @@ static int transcode_subtitles(InputStream *ist, const AVPacket *pkt, int ret = avcodec_decode_subtitle2(ist->dec_ctx, &subtitle, got_output, pkt); -check_decode_result(NULL, got_output, ret); +check_decode_result(ist, got_output, ret); if (ret < 0 || !*got_output) { *decode_failed = 1; -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 15/36] fftools/ffmpeg_filter: make input filter configured parameters private
They are not used outside of ffmpeg_filter. --- fftools/ffmpeg.h| 9 - fftools/ffmpeg_filter.c | 89 +++-- 2 files changed, 50 insertions(+), 48 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 189454d629..9cb9f35bc2 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -283,15 +283,6 @@ typedef struct InputFilter { struct FilterGraph *graph; uint8_t*name; enum AVMediaTypetype; // AVMEDIA_TYPE_SUBTITLE for sub2video - -// parameters configured for this input -int format; - -int width, height; -AVRational sample_aspect_ratio; - -int sample_rate; -AVChannelLayout ch_layout; } InputFilter; typedef struct OutputFilter { diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index d85d9e2c67..12e756e489 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -60,6 +60,15 @@ typedef struct InputFilterPriv { int eof; +// parameters configured for this input +int format; + +int width, height; +AVRational sample_aspect_ratio; + +int sample_rate; +AVChannelLayout ch_layout; + AVRational time_base; AVFifo *frame_queue; @@ -245,12 +254,12 @@ static InputFilter *ifilter_alloc(FilterGraph *fg) InputFilter *ifilter = &ifp->ifilter; ifilter->graph = fg; -ifilter->format = -1; ifp->frame = av_frame_alloc(); if (!ifp->frame) report_and_exit(AVERROR(ENOMEM)); +ifp->format = -1; ifp->fallback.format = -1; ifp->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW); @@ -956,14 +965,15 @@ void check_filter_outputs(void) static int sub2video_prepare(InputStream *ist, InputFilter *ifilter) { +InputFilterPriv *ifp = ifp_from_ifilter(ifilter); AVFormatContext *avf = input_files[ist->file_index]->ctx; int i, w, h; /* Compute the size of the canvas for the subtitles stream. If the subtitles codecpar has set a size, use it. Otherwise use the maximum dimensions of the video streams in the same file. */ -w = ifilter->width; -h = ifilter->height; +w = ifp->width; +h = ifp->height; if (!(w && h)) { for (i = 0; i < avf->nb_streams; i++) { if (avf->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { @@ -977,15 +987,15 @@ static int sub2video_prepare(InputStream *ist, InputFilter *ifilter) } av_log(avf, AV_LOG_INFO, "sub2video: using %dx%d canvas\n", w, h); } -ist->sub2video.w = ifilter->width = w; -ist->sub2video.h = ifilter->height = h; +ist->sub2video.w = ifp->width = w; +ist->sub2video.h = ifp->height = h; -ifilter->width = ist->dec_ctx->width ? ist->dec_ctx->width : ist->sub2video.w; -ifilter->height = ist->dec_ctx->height ? ist->dec_ctx->height : ist->sub2video.h; +ifp->width = ist->dec_ctx->width ? ist->dec_ctx->width : ist->sub2video.w; +ifp->height = ist->dec_ctx->height ? ist->dec_ctx->height : ist->sub2video.h; /* rectangles are AV_PIX_FMT_PAL8, but we have no guarantee that the palettes for all rectangles are identical or compatible */ -ifilter->format = AV_PIX_FMT_RGB32; +ifp->format = AV_PIX_FMT_RGB32; ist->sub2video.frame = av_frame_alloc(); if (!ist->sub2video.frame) @@ -1042,14 +1052,14 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, ifp->time_base = ist->framerate.num ? av_inv_q(ist->framerate) : ist->st->time_base; -sar = ifilter->sample_aspect_ratio; +sar = ifp->sample_aspect_ratio; if(!sar.den) sar = (AVRational){0,1}; av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC); av_bprintf(&args, "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:" "pixel_aspect=%d/%d", - ifilter->width, ifilter->height, ifilter->format, + ifp->width, ifp->height, ifp->format, ifp->time_base.num, ifp->time_base.den, sar.num, sar.den); if (fr.num && fr.den) av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den); @@ -1067,7 +1077,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, av_freep(&par); last_filter = ifilter->filter; -desc = av_pix_fmt_desc_get(ifilter->format); +desc = av_pix_fmt_desc_get(ifp->format); av_assert0(desc); // TODO: insert hwaccel enabled filters like transpose_vaapi into the graph @@ -1147,19 +1157,19 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter, return AVERROR(EINVAL); } -ifp->time_base = (AVRational){ 1, ifilter->sample_rate }; +ifp->time_base = (AVRational){ 1, ifp->sample_rate }; av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC); av_bprintf(&args, "time_base=%d/%d:sample_rate=%d:sample_fmt=%s", ifp->time_bas
[FFmpeg-devel] [PATCH 05/36] fftools/ffmpeg_filter: make sure pkt_duration matches duration
Otherwise the two values might get desynchronized and lavfi can prefer the wrong one. --- fftools/ffmpeg_filter.c | 5 + 1 file changed, 5 insertions(+) diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 95ffa0f087..274eefe11c 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -1622,6 +1622,11 @@ int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference) frame->pts = av_rescale_q(frame->pts, frame->time_base, ifp->time_base); frame->duration = av_rescale_q(frame->duration, frame->time_base, ifp->time_base); frame->time_base = ifp->time_base; +#if LIBAVUTIL_VERSION_MAJOR < 59 +AV_NOWARN_DEPRECATED( +frame->pkt_duration = frame->duration; +) +#endif ret = av_buffersrc_add_frame_flags(ifilter->filter, frame, AV_BUFFERSRC_FLAG_PUSH); -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 12/36] fftools/ffmpeg_filter: only use fallback parameters when necessary
With complex filtergraphs it can happen that the filtergraph is unconfigured because some other filter than the one we just got EOF on is missing parameters. Make sure that the fallback parametes for a given input are only used when that input is unconfigured. --- fftools/ffmpeg_filter.c | 24 +--- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 2c3e2a96f7..8eca0f2cae 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -1521,17 +1521,19 @@ int ifilter_send_eof(InputFilter *ifilter, int64_t pts, AVRational tb) if (ret < 0) return ret; } else { -// the filtergraph was never configured, use the fallback parameters -ifilter->format = ifp->fallback.format; -ifilter->sample_rate= ifp->fallback.sample_rate; -ifilter->width = ifp->fallback.width; -ifilter->height = ifp->fallback.height; -ifilter->sample_aspect_ratio= ifp->fallback.sample_aspect_ratio; - -ret = av_channel_layout_copy(&ifilter->ch_layout, - &ifp->fallback.ch_layout); -if (ret < 0) -return ret; +if (ifilter->format < 0) { +// the filtergraph was never configured, use the fallback parameters +ifilter->format = ifp->fallback.format; +ifilter->sample_rate= ifp->fallback.sample_rate; +ifilter->width = ifp->fallback.width; +ifilter->height = ifp->fallback.height; +ifilter->sample_aspect_ratio= ifp->fallback.sample_aspect_ratio; + +ret = av_channel_layout_copy(&ifilter->ch_layout, + &ifp->fallback.ch_layout); +if (ret < 0) +return ret; +} if (ifilter->format < 0 && (ifilter->type == AVMEDIA_TYPE_AUDIO || ifilter->type == AVMEDIA_TYPE_VIDEO)) { av_log(NULL, AV_LOG_ERROR, "Cannot determine format of input stream %d:%d after EOF\n", ifilter->ist->file_index, ifilter->ist->st->index); -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 19/36] fftools/ffmpeg_filter: keep track of the real filter input type
Avoid extracting it from various remote sources. --- fftools/ffmpeg_filter.c | 21 ++--- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 5656fa87df..c699431831 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -60,8 +60,11 @@ typedef struct InputFilterPriv { // used to hold submitted input AVFrame *frame; -// AVMEDIA_TYPE_SUBTITLE for sub2video +// filter data type enum AVMediaType type; +// source data type: AVMEDIA_TYPE_SUBTITLE for sub2video, +// same as type otherwise +enum AVMediaType type_src; int eof; @@ -267,7 +270,9 @@ static InputFilter *ifilter_alloc(FilterGraph *fg, InputStream *ist) ifp->format = -1; ifp->fallback.format = -1; ifp->ist = ist; -ifp->type= ist->st->codecpar->codec_type; +ifp->type_src= ist->st->codecpar->codec_type; +ifp->type= ifp->type_src == AVMEDIA_TYPE_SUBTITLE ? + AVMEDIA_TYPE_VIDEO : ifp->type_src; ifp->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW); if (!ifp->frame_queue) @@ -1205,7 +1210,7 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter, static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter, AVFilterInOut *in) { -switch (avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx)) { +switch (ifp_from_ifilter(ifilter)->type) { case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, ifilter, in); case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, ifilter, in); default: av_assert0(0); return 0; @@ -1459,8 +1464,8 @@ int ifilter_has_all_input_formats(FilterGraph *fg) int i; for (i = 0; i < fg->nb_inputs; i++) { InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]); -if (ifp->format < 0 && (ifp->type == AVMEDIA_TYPE_AUDIO || -ifp->type == AVMEDIA_TYPE_VIDEO)) +if (ifp->format < 0 && (ifp->type_src == AVMEDIA_TYPE_AUDIO || +ifp->type_src == AVMEDIA_TYPE_VIDEO)) return 0; } return 1; @@ -1564,7 +1569,9 @@ int ifilter_send_eof(InputFilter *ifilter, int64_t pts, AVRational tb) } } -if (ifp->format < 0 && (ifp->type == AVMEDIA_TYPE_AUDIO || ifp->type == AVMEDIA_TYPE_VIDEO)) { +if (ifp->format < 0 && +(ifp->type_src == AVMEDIA_TYPE_AUDIO || + ifp->type_src == AVMEDIA_TYPE_VIDEO)) { av_log(NULL, AV_LOG_ERROR, "Cannot determine format of input stream %d:%d after EOF\n", ifp->ist->file_index, ifp->ist->st->index); @@ -1585,7 +1592,7 @@ int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference) /* determine if the parameters for this input changed */ need_reinit = ifp->format != frame->format; -switch (ifp->ist->par->codec_type) { +switch (ifp->type) { case AVMEDIA_TYPE_AUDIO: need_reinit |= ifp->sample_rate!= frame->sample_rate || av_channel_layout_compare(&ifp->ch_layout, &frame->ch_layout); -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 16/36] fftools/ffmpeg_filter: drop a redundant error message
In case no decoder is available, dec_open() called from ist_use() will fail with 'Decoding requested, but no decoder found', so this check is redundant. --- fftools/ffmpeg_filter.c | 6 -- 1 file changed, 6 deletions(-) diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 12e756e489..16f29a313f 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -1201,12 +1201,6 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter, static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter, AVFilterInOut *in) { -if (!ifilter->ist->dec) { -av_log(NULL, AV_LOG_ERROR, - "No decoder for stream #%d:%d, filtering impossible\n", - ifilter->ist->file_index, ifilter->ist->st->index); -return AVERROR_DECODER_NOT_FOUND; -} switch (avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx)) { case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, ifilter, in); case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, ifilter, in); -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 14/36] fftools/ffmpeg: move ifilter_has_all_input_formats() to ffmpeg_filter
That is a more appropriate place for that function. --- fftools/ffmpeg.c| 12 fftools/ffmpeg_filter.c | 12 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index e368f5a148..9d554e2fb0 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -787,18 +787,6 @@ static void check_decode_result(InputStream *ist, int *got_output, int ret) } } -// Filters can be configured only if the formats of all inputs are known. -int ifilter_has_all_input_formats(FilterGraph *fg) -{ -int i; -for (i = 0; i < fg->nb_inputs; i++) { -if (fg->inputs[i]->format < 0 && (fg->inputs[i]->type == AVMEDIA_TYPE_AUDIO || - fg->inputs[i]->type == AVMEDIA_TYPE_VIDEO)) -return 0; -} -return 1; -} - // This does not quite work like avcodec_decode_audio4/avcodec_decode_video2. // There is the following difference: if you got a frame, you must call // it again with pkt=NULL. pkt==NULL is treated differently from pkt->size==0 diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 6323278d15..d85d9e2c67 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -1445,6 +1445,18 @@ static int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *fr return 0; } +// Filters can be configured only if the formats of all inputs are known. +int ifilter_has_all_input_formats(FilterGraph *fg) +{ +int i; +for (i = 0; i < fg->nb_inputs; i++) { +if (fg->inputs[i]->format < 0 && (fg->inputs[i]->type == AVMEDIA_TYPE_AUDIO || + fg->inputs[i]->type == AVMEDIA_TYPE_VIDEO)) +return 0; +} +return 1; +} + int filtergraph_is_simple(FilterGraph *fg) { FilterGraphPriv *fgp = fgp_from_fg(fg); -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 24/36] fftools/ffmpeg: replace an unreachable return with av_assert0(0)
This cannot be reached, because initialization will fail if decoding is requested for a stream but no decoder can be found. --- fftools/ffmpeg.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 62620bacce..1fcabd123a 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -1390,8 +1390,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo ret = AVERROR_EOF; av_packet_unref(avpkt); break; -default: -return -1; +default: av_assert0(0); } if (ret == AVERROR_EOF) { -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 22/36] fftools/ffmpeg: drop an obsolete hack
This special handling for decoder flushing has not been needed since af1761f7b5, as the filtergraph actually is drained after that commit. --- fftools/ffmpeg.c | 11 --- 1 file changed, 11 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 9d554e2fb0..49313edebc 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -1418,17 +1418,6 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo if (!got_output) break; -// During draining, we might get multiple output frames in this loop. -// ffmpeg.c does not drain the filter chain on configuration changes, -// which means if we send multiple frames at once to the filters, and -// one of those frames changes configuration, the buffered frames will -// be lost. This can upset certain FATE tests. -// Decode only 1 frame per call on EOF to appease these FATE tests. -// The ideal solution would be to rewrite decoding to use the new -// decoding API in a better way. -if (!pkt) -break; - repeating = 1; } -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 23/36] fftools/ffmpeg: eliminate InputStream.got_output
It tracks whether the decoder for this stream ever produced any frames and its only use is for checking whether a filter input ever received a frame - those that did not are prioritized by the scheduler. This is awkward and unnecessarily complicated - checking whether the filtergraph input format is valid works just as well and does not require maintaining an extra variable. --- fftools/ffmpeg.c| 3 --- fftools/ffmpeg.h| 2 -- fftools/ffmpeg_filter.c | 2 +- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 49313edebc..62620bacce 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -1412,9 +1412,6 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo break; } -if (got_output) -ist->got_output = 1; - if (!got_output) break; diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 04c41a5311..3a332768df 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -413,8 +413,6 @@ typedef struct InputStream { // number of frames/samples retrieved from the decoder uint64_t frames_decoded; uint64_t samples_decoded; - -int got_output; } InputStream; typedef struct LastFrameDuration { diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 6f842f6b46..640ecec067 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -1700,7 +1700,7 @@ int fg_transcode_step(FilterGraph *graph, InputStream **best_ist) for (int i = 0; i < graph->nb_inputs; i++) { InputFilter *ifilter = graph->inputs[i]; InputFilterPriv *ifp = ifp_from_ifilter(ifilter); -if (!ifp->ist->got_output && !ifp->eof) { +if (ifp->format < 0 && !ifp->eof) { *best_ist = ifp->ist; return 0; } -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 27/36] fftools/ffmpeg: move a block to a more appropriate place
New placement requires fewer explicit conditions and is easier to understand. The logic should be exactly equivalent, since this is the only place where eof_reached is set for decoding. --- fftools/ffmpeg.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 2e9a2b940a..4cf8b54dc0 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -1393,6 +1393,16 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo } if (ret == AVERROR_EOF) { +/* after flushing, send an EOF on all the filter inputs attached to the stream */ +/* except when looping we need to flush but not to send an EOF */ +if (!no_eof) { +ret = send_filter_eof(ist); +if (ret < 0) { +av_log(NULL, AV_LOG_FATAL, "Error marking filters as finished\n"); +exit_program(1); +} +} + eof_reached = 1; break; } @@ -1416,16 +1426,6 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo repeating = 1; } -/* after flushing, send an EOF on all the filter inputs attached to the stream */ -/* except when looping we need to flush but not to send an EOF */ -if (!pkt && ist->decoding_needed && eof_reached && !no_eof) { -int ret = send_filter_eof(ist); -if (ret < 0) { -av_log(NULL, AV_LOG_FATAL, "Error marking filters as finished\n"); -exit_program(1); -} -} - if (!pkt && !ist->decoding_needed) eof_reached = 1; -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 29/36] fftools/ffmpeg: move decoding code to ffmpeg_dec
--- fftools/ffmpeg.c | 534 -- fftools/ffmpeg.h | 12 + fftools/ffmpeg_dec.c | 538 +++ 3 files changed, 550 insertions(+), 534 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index e84add50e5..baa2f95f5d 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -283,20 +283,6 @@ static void sub2video_heartbeat(InputStream *ist, int64_t pts) } } -static void sub2video_flush(InputStream *ist) -{ -int i; -int ret; - -if (ist->sub2video.end_pts < INT64_MAX) -sub2video_update(ist, INT64_MAX, NULL); -for (i = 0; i < ist->nb_filters; i++) { -ret = av_buffersrc_add_frame(ist->filters[i]->filter, NULL); -if (ret != AVERROR_EOF && ret < 0) -av_log(NULL, AV_LOG_WARNING, "Flush the frame error.\n"); -} -} - /* end of sub2video hack */ static void term_exit_sigsafe(void) @@ -768,417 +754,6 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti first_report = 0; } -static void check_decode_result(InputStream *ist, int *got_output, int ret) -{ -if (ret < 0) -ist->decode_errors++; - -if (ret < 0 && exit_on_error) -exit_program(1); - -if (*got_output && ist->dec_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE) { -if (ist->decoded_frame->decode_error_flags || (ist->decoded_frame->flags & AV_FRAME_FLAG_CORRUPT)) { -av_log(ist, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING, - "corrupt decoded frame\n"); -if (exit_on_error) -exit_program(1); -} -} -} - -// This does not quite work like avcodec_decode_audio4/avcodec_decode_video2. -// There is the following difference: if you got a frame, you must call -// it again with pkt=NULL. pkt==NULL is treated differently from pkt->size==0 -// (pkt==NULL means get more output, pkt->size==0 is a flush/drain packet) -static int decode(InputStream *ist, AVCodecContext *avctx, - AVFrame *frame, int *got_frame, const AVPacket *pkt) -{ -int ret; - -*got_frame = 0; - -if (pkt) { -ret = avcodec_send_packet(avctx, pkt); -// In particular, we don't expect AVERROR(EAGAIN), because we read all -// decoded frames with avcodec_receive_frame() until done. -if (ret < 0 && ret != AVERROR_EOF) -return ret; -} - -ret = avcodec_receive_frame(avctx, frame); -if (ret < 0 && ret != AVERROR(EAGAIN)) -return ret; -if (ret >= 0) { -if (ist->want_frame_data) { -FrameData *fd; - -av_assert0(!frame->opaque_ref); -frame->opaque_ref = av_buffer_allocz(sizeof(*fd)); -if (!frame->opaque_ref) { -av_frame_unref(frame); -return AVERROR(ENOMEM); -} -fd = (FrameData*)frame->opaque_ref->data; -fd->pts = frame->pts; -fd->tb = avctx->pkt_timebase; -fd->idx = avctx->frame_num - 1; -} - -frame->time_base = avctx->pkt_timebase; - -*got_frame = 1; -} - -return 0; -} - -static int send_frame_to_filters(InputStream *ist, AVFrame *decoded_frame) -{ -int i, ret; - -av_assert1(ist->nb_filters > 0); /* ensure ret is initialized */ -for (i = 0; i < ist->nb_filters; i++) { -ret = ifilter_send_frame(ist->filters[i], decoded_frame, i < ist->nb_filters - 1); -if (ret == AVERROR_EOF) -ret = 0; /* ignore */ -if (ret < 0) { -av_log(NULL, AV_LOG_ERROR, - "Failed to inject frame into filter network: %s\n", av_err2str(ret)); -break; -} -} -return ret; -} - -static AVRational audio_samplerate_update(InputStream *ist, const AVFrame *frame) -{ -const int prev = ist->last_frame_tb.den; -const int sr = frame->sample_rate; - -AVRational tb_new; -int64_t gcd; - -if (frame->sample_rate == ist->last_frame_sample_rate) -goto finish; - -gcd = av_gcd(prev, sr); - -if (prev / gcd >= INT_MAX / sr) { -av_log(ist, AV_LOG_WARNING, - "Audio timestamps cannot be represented exactly after " - "sample rate change: %d -> %d\n", prev, sr); - -// LCM of 192000, 44100, allows to represent all common samplerates -tb_new = (AVRational){ 1, 28224000 }; -} else -tb_new = (AVRational){ 1, prev / gcd * sr }; - -// keep the frame timebase if it is strictly better than -// the samplerate-defined one -if (frame->time_base.num == 1 && frame->time_base.den > tb_new.den && -!(frame->time_base.den % tb_new.den)) -tb_new = frame->time_base; - -if (ist->last_frame_pts != AV_NOPTS_VALUE) -ist->last_frame_pts = av_rescale_q(ist->last_frame_pts, - ist->last_frame_tb, tb_new); -ist->last_frame_duration_est = av_resca
[FFmpeg-devel] [PATCH 26/36] fftools/ffmpeg: rework handling -max_error_rate
Replace the decode_error_stat global with a per-input-stream variable. Also, print an error message when the error rate is exceeded. --- fftools/ffmpeg.c | 28 fftools/ffmpeg.h | 1 + fftools/ffmpeg_demux.c | 5 +++-- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 537f287637..2e9a2b940a 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -121,7 +121,6 @@ static int64_t getmaxrss(void); int64_t nb_frames_dup = 0; int64_t nb_frames_drop = 0; -static int64_t decode_error_stat[2]; unsigned nb_output_dumped = 0; static BenchmarkTimeStamps current_time; @@ -771,8 +770,8 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti static void check_decode_result(InputStream *ist, int *got_output, int ret) { -if (*got_output || ret<0) -decode_error_stat[ret<0] ++; +if (ret < 0) +ist->decode_errors++; if (ret < 0 && exit_on_error) exit_program(1); @@ -1807,14 +1806,15 @@ static int transcode_step(OutputStream *ost) /* * The following code is the main loop of the file converter */ -static int transcode(void) +static int transcode(int *err_rate_exceeded) { -int ret, i; +int ret = 0, i; InputStream *ist; int64_t timer_start; print_stream_maps(); +*err_rate_exceeded = 0; atomic_store(&transcode_init_done, 1); if (stdin_interaction) { @@ -1858,6 +1858,12 @@ static int transcode(void) if (!input_files[ist->file_index]->eof_reached) { process_input_packet(ist, NULL, 0); } + +if ((ist->frames_decoded + ist->decode_errors) * max_error_rate < ist->decode_errors) { +av_log(ist, AV_LOG_FATAL, "Maximum error rate %g exceeded\n", max_error_rate); +*err_rate_exceeded = 1; +} + } enc_flush(); @@ -1921,7 +1927,7 @@ static int64_t getmaxrss(void) int main(int argc, char **argv) { -int ret; +int ret, err_rate_exceeded; BenchmarkTimeStamps ti; init_dynload(); @@ -1958,7 +1964,7 @@ int main(int argc, char **argv) } current_time = ti = get_benchmark_time_stamps(); -ret = transcode(); +ret = transcode(&err_rate_exceeded); if (ret >= 0 && do_benchmark) { int64_t utime, stime, rtime; current_time = get_benchmark_time_stamps(); @@ -1969,12 +1975,10 @@ int main(int argc, char **argv) "bench: utime=%0.3fs stime=%0.3fs rtime=%0.3fs\n", utime / 100.0, stime / 100.0, rtime / 100.0); } -av_log(NULL, AV_LOG_DEBUG, "%"PRIu64" frames successfully decoded, %"PRIu64" decoding errors\n", - decode_error_stat[0], decode_error_stat[1]); -if ((decode_error_stat[0] + decode_error_stat[1]) * max_error_rate < decode_error_stat[1]) -exit_program(69); -ret = received_nb_signals ? 255 : ret; +ret = received_nb_signals ? 255 : + err_rate_exceeded ? 69 : ret; + exit_program(ret); return ret; } diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 3a332768df..87e684a147 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -413,6 +413,7 @@ typedef struct InputStream { // number of frames/samples retrieved from the decoder uint64_t frames_decoded; uint64_t samples_decoded; +uint64_t decode_errors; } InputStream; typedef struct LastFrameDuration { diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index df87e0f30a..401ae1f850 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -786,8 +786,9 @@ static void demux_final_stats(Demuxer *d) ds->nb_packets, ds->data_size); if (ist->decoding_needed) { -av_log(f, AV_LOG_VERBOSE, "%"PRIu64" frames decoded", - ist->frames_decoded); +av_log(f, AV_LOG_VERBOSE, + "%"PRIu64" frames decoded; %"PRIu64" decode errors", + ist->frames_decoded, ist->decode_errors); if (type == AVMEDIA_TYPE_AUDIO) av_log(f, AV_LOG_VERBOSE, " (%"PRIu64" samples)", ist->samples_decoded); av_log(f, AV_LOG_VERBOSE, "; "); -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 17/36] fftools/ffmpeg_filter: move InputFilter.ist to private data
It is not accessed outside of ffmpeg_filter. --- fftools/ffmpeg.h| 1 - fftools/ffmpeg_filter.c | 34 +++--- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 9cb9f35bc2..c33e537faa 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -279,7 +279,6 @@ typedef struct OptionsContext { typedef struct InputFilter { AVFilterContext*filter; -struct InputStream *ist; struct FilterGraph *graph; uint8_t*name; enum AVMediaTypetype; // AVMEDIA_TYPE_SUBTITLE for sub2video diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 16f29a313f..e6e9e00985 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -55,6 +55,8 @@ static FilterGraphPriv *fgp_from_fg(FilterGraph *fg) typedef struct InputFilterPriv { InputFilter ifilter; +InputStream *ist; + // used to hold submitted input AVFrame *frame; @@ -247,7 +249,7 @@ static OutputFilter *ofilter_alloc(FilterGraph *fg) return ofilter; } -static InputFilter *ifilter_alloc(FilterGraph *fg) +static InputFilter *ifilter_alloc(FilterGraph *fg, InputStream *ist) { InputFilterPriv *ifp = allocate_array_elem(&fg->inputs, sizeof(*ifp), &fg->nb_inputs); @@ -261,6 +263,7 @@ static InputFilter *ifilter_alloc(FilterGraph *fg) ifp->format = -1; ifp->fallback.format = -1; +ifp->ist = ist; ifp->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW); if (!ifp->frame_queue) @@ -282,7 +285,7 @@ void fg_free(FilterGraph **pfg) for (int j = 0; j < fg->nb_inputs; j++) { InputFilter *ifilter = fg->inputs[j]; InputFilterPriv *ifp = ifp_from_ifilter(ifilter); -struct InputStream *ist = ifilter->ist; +InputStream *ist = ifp->ist; if (ifp->frame_queue) { AVFrame *frame; @@ -354,8 +357,7 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost) ost->filter = ofilter; -ifilter = ifilter_alloc(fg); -ifilter->ist= ist; +ifilter = ifilter_alloc(fg, ist); ret = ist_filter_add(ist, ifilter, 1); if (ret < 0) @@ -437,8 +439,8 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) } av_assert0(ist); -ifilter = ifilter_alloc(fg); -ifilter->ist= ist; +ifilter = ifilter_alloc(fg, ist); + ifilter->type = ist->st->codecpar->codec_type; ifilter->name = describe_filter_link(fg, in, 1); @@ -1019,7 +1021,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, AVFilterContext *last_filter; const AVFilter *buffer_filt = avfilter_get_by_name("buffer"); const AVPixFmtDescriptor *desc; -InputStream *ist = ifilter->ist; +InputStream *ist = ifp->ist; InputFile *f = input_files[ist->file_index]; AVRational fr = ist->framerate; AVRational sar; @@ -1145,7 +1147,7 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter, InputFilterPriv *ifp = ifp_from_ifilter(ifilter); AVFilterContext *last_filter; const AVFilter *abuffer_filt = avfilter_get_by_name("abuffer"); -InputStream *ist = ifilter->ist; +InputStream *ist = ifp->ist; InputFile *f = input_files[ist->file_index]; AVBPrint args; char name[255]; @@ -1380,7 +1382,7 @@ int configure_filtergraph(FilterGraph *fg) /* process queued up subtitle packets */ for (i = 0; i < fg->nb_inputs; i++) { -InputStream *ist = fg->inputs[i]->ist; +InputStream *ist = ifp_from_ifilter(fg->inputs[i])->ist; if (ist->sub2video.sub_queue && ist->sub2video.frame) { AVSubtitle tmp; while (av_fifo_read(ist->sub2video.sub_queue, &tmp, 1) >= 0) { @@ -1561,7 +1563,9 @@ int ifilter_send_eof(InputFilter *ifilter, int64_t pts, AVRational tb) } if (ifp->format < 0 && (ifilter->type == AVMEDIA_TYPE_AUDIO || ifilter->type == AVMEDIA_TYPE_VIDEO)) { -av_log(NULL, AV_LOG_ERROR, "Cannot determine format of input stream %d:%d after EOF\n", ifilter->ist->file_index, ifilter->ist->st->index); +av_log(NULL, AV_LOG_ERROR, + "Cannot determine format of input stream %d:%d after EOF\n", + ifp->ist->file_index, ifp->ist->st->index); return AVERROR_INVALIDDATA; } } @@ -1579,7 +1583,7 @@ int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference) /* determine if the parameters for this input changed */ need_reinit = ifp->format != frame->format; -switch (ifilter->ist->par->codec_type) { +switch (ifp->ist->par->codec_type) { case AVMEDIA_TYPE_AUDIO: need_reinit |= ifp->sample_rate!= frame->sample_rate || av_channel_layout_compare(&ifp
[FFmpeg-devel] [PATCH v2] lavc/h264chroma: RISC-V V add motion compensation for 8x8 chroma blocks
Optimize the put and avg filtering for 8x8 chroma blocks Signed-off-by: Arnie Chang --- libavcodec/h264chroma.c | 2 + libavcodec/h264chroma.h | 1 + libavcodec/riscv/Makefile | 3 + libavcodec/riscv/h264_chroma_init_riscv.c | 39 ++ libavcodec/riscv/h264_mc_chroma.S | 492 ++ libavcodec/riscv/h264_mc_chroma.h | 34 ++ 6 files changed, 571 insertions(+) create mode 100644 libavcodec/riscv/h264_chroma_init_riscv.c create mode 100644 libavcodec/riscv/h264_mc_chroma.S create mode 100644 libavcodec/riscv/h264_mc_chroma.h diff --git a/libavcodec/h264chroma.c b/libavcodec/h264chroma.c index 60b86b6fba..1eeab7bc40 100644 --- a/libavcodec/h264chroma.c +++ b/libavcodec/h264chroma.c @@ -58,5 +58,7 @@ av_cold void ff_h264chroma_init(H264ChromaContext *c, int bit_depth) ff_h264chroma_init_mips(c, bit_depth); #elif ARCH_LOONGARCH64 ff_h264chroma_init_loongarch(c, bit_depth); +#elif ARCH_RISCV +ff_h264chroma_init_riscv(c, bit_depth); #endif } diff --git a/libavcodec/h264chroma.h b/libavcodec/h264chroma.h index b8f9c8f4fc..9c81c18a76 100644 --- a/libavcodec/h264chroma.h +++ b/libavcodec/h264chroma.h @@ -37,5 +37,6 @@ void ff_h264chroma_init_ppc(H264ChromaContext *c, int bit_depth); void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth); void ff_h264chroma_init_mips(H264ChromaContext *c, int bit_depth); void ff_h264chroma_init_loongarch(H264ChromaContext *c, int bit_depth); +void ff_h264chroma_init_riscv(H264ChromaContext *c, int bit_depth); #endif /* AVCODEC_H264CHROMA_H */ diff --git a/libavcodec/riscv/Makefile b/libavcodec/riscv/Makefile index 965942f4df..08b76c93cb 100644 --- a/libavcodec/riscv/Makefile +++ b/libavcodec/riscv/Makefile @@ -19,3 +19,6 @@ OBJS-$(CONFIG_PIXBLOCKDSP) += riscv/pixblockdsp_init.o \ RVV-OBJS-$(CONFIG_PIXBLOCKDSP) += riscv/pixblockdsp_rvv.o OBJS-$(CONFIG_VORBIS_DECODER) += riscv/vorbisdsp_init.o RVV-OBJS-$(CONFIG_VORBIS_DECODER) += riscv/vorbisdsp_rvv.o + +OBJS-$(CONFIG_H264CHROMA) += riscv/h264_chroma_init_riscv.o +RVV-OBJS-$(CONFIG_H264CHROMA) += riscv/h264_mc_chroma.o diff --git a/libavcodec/riscv/h264_chroma_init_riscv.c b/libavcodec/riscv/h264_chroma_init_riscv.c new file mode 100644 index 00..b6f98ba693 --- /dev/null +++ b/libavcodec/riscv/h264_chroma_init_riscv.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 SiFive, Inc. All rights reserved. + * + * 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 + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavcodec/h264chroma.h" +#include "config.h" +#include "h264_mc_chroma.h" + +av_cold void ff_h264chroma_init_riscv(H264ChromaContext *c, int bit_depth) +{ +#if HAVE_RVV +const int high_bit_depth = bit_depth > 8; + +if (!high_bit_depth) { +c->put_h264_chroma_pixels_tab[0] = h264_put_chroma_mc8_rvv; +c->avg_h264_chroma_pixels_tab[0] = h264_avg_chroma_mc8_rvv; +} +#endif +} \ No newline at end of file diff --git a/libavcodec/riscv/h264_mc_chroma.S b/libavcodec/riscv/h264_mc_chroma.S new file mode 100644 index 00..a02866f633 --- /dev/null +++ b/libavcodec/riscv/h264_mc_chroma.S @@ -0,0 +1,492 @@ +/* + * Copyright (c) 2023 SiFive, Inc. All rights reserved. + * + * 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 + */ +.text + +.globlh264_put_chroma_mc8_rvv +.p2align1 +.typeh264_put_chroma_mc8_rvv,@function +h264_put_chroma_mc8_rvv: +slliwt2, a5, 3 +mulwt1, a5, a4 +sh3add
[FFmpeg-devel] [PATCH 32/36] fftools/ffmpeg: reindent after previous commit
--- fftools/ffmpeg_dec.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c index 73f826c76a..58bb7a7344 100644 --- a/fftools/ffmpeg_dec.c +++ b/fftools/ffmpeg_dec.c @@ -232,17 +232,17 @@ static int decode_video(InputStream *ist, AVFrame *frame) ist->par->video_delay); } -if (ist->dec_ctx->width != frame->width || -ist->dec_ctx->height != frame->height || -ist->dec_ctx->pix_fmt != frame->format) { -av_log(NULL, AV_LOG_DEBUG, "Frame parameters mismatch context %d,%d,%d != %d,%d,%d\n", -frame->width, -frame->height, -frame->format, -ist->dec_ctx->width, -ist->dec_ctx->height, -ist->dec_ctx->pix_fmt); -} +if (ist->dec_ctx->width != frame->width || +ist->dec_ctx->height != frame->height || +ist->dec_ctx->pix_fmt != frame->format) { +av_log(NULL, AV_LOG_DEBUG, "Frame parameters mismatch context %d,%d,%d != %d,%d,%d\n", +frame->width, +frame->height, +frame->format, +ist->dec_ctx->width, +ist->dec_ctx->height, +ist->dec_ctx->pix_fmt); +} if(ist->top_field_first>=0) frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 34/36] fftools/ffmpeg_dec: deduplicate code in decode_audio/video()
--- fftools/ffmpeg_dec.c | 28 +++- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c index 79e9c04fc1..4662d0a265 100644 --- a/fftools/ffmpeg_dec.c +++ b/fftools/ffmpeg_dec.c @@ -130,18 +130,13 @@ static void audio_ts_process(InputStream *ist, AVFrame *frame) static int decode_audio(InputStream *ist, AVFrame *decoded_frame) { -int ret, err = 0; - ist->samples_decoded += decoded_frame->nb_samples; -ist->frames_decoded++; audio_ts_process(ist, decoded_frame); ist->nb_samples = decoded_frame->nb_samples; -err = send_frame_to_filters(ist, decoded_frame); -av_frame_unref(decoded_frame); -return err < 0 ? err : ret; +return 0; } static int64_t video_duration_estimate(const InputStream *ist, const AVFrame *frame) @@ -197,8 +192,6 @@ static int64_t video_duration_estimate(const InputStream *ist, const AVFrame *fr static int decode_video(InputStream *ist, AVFrame *frame) { -int ret = 0, err = 0; - // The following line may be required in some cases where there is no parser // or the parser does not has_b_frames correctly if (ist->par->video_delay < ist->dec_ctx->has_b_frames) { @@ -229,12 +222,10 @@ static int decode_video(InputStream *ist, AVFrame *frame) if(ist->top_field_first>=0) frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; -ist->frames_decoded++; - if (ist->hwaccel_retrieve_data && frame->format == ist->hwaccel_pix_fmt) { -err = ist->hwaccel_retrieve_data(ist->dec_ctx, frame); +int err = ist->hwaccel_retrieve_data(ist->dec_ctx, frame); if (err < 0) -goto fail; +return err; } frame->pts = frame->best_effort_timestamp; @@ -275,11 +266,7 @@ static int decode_video(InputStream *ist, AVFrame *frame) if (ist->st->sample_aspect_ratio.num) frame->sample_aspect_ratio = ist->st->sample_aspect_ratio; -err = send_frame_to_filters(ist, frame); - -fail: -av_frame_unref(frame); -return err < 0 ? err : ret; +return 0; } static void sub2video_flush(InputStream *ist) @@ -485,6 +472,13 @@ int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof) "data for stream #%d:%d\n", ist->file_index, ist->st->index); exit_program(1); } + +ist->frames_decoded++; + +ret = send_frame_to_filters(ist, frame); +av_frame_unref(frame); +if (ret < 0) +exit_program(1); } } -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 30/36] fftools/ffmpeg_dec: deobfuscate subtitle decoding
It is currently handled in the same loop as audio and video, but this obscures the actual flow, because only one iteration is ever performed for subtitles. Also, avoid a pointless packet reference. --- fftools/ffmpeg_dec.c | 34 ++ 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c index 30fe75d8a6..646b587f9e 100644 --- a/fftools/ffmpeg_dec.c +++ b/fftools/ffmpeg_dec.c @@ -456,25 +456,31 @@ out: return ret; } -static int transcode_subtitles(InputStream *ist, const AVPacket *pkt, - int *got_output, int *decode_failed) +static int transcode_subtitles(InputStream *ist, const AVPacket *pkt) { AVSubtitle subtitle; +int got_output; int ret = avcodec_decode_subtitle2(ist->dec_ctx, - &subtitle, got_output, pkt); + &subtitle, &got_output, pkt); -check_decode_result(ist, got_output, ret); +if (ret < 0) { +av_log(ist, AV_LOG_ERROR, "Error decoding subtitles: %s\n", +av_err2str(ret)); +if (exit_on_error) +exit_program(1); +} -if (ret < 0 || !*got_output) { -*decode_failed = 1; +check_decode_result(ist, &got_output, ret); + +if (ret < 0 || !got_output) { if (!pkt->size) sub2video_flush(ist); -return ret; +return ret < 0 ? ret : AVERROR_EOF; } ist->frames_decoded++; -return process_subtitle(ist, &subtitle, got_output); +return process_subtitle(ist, &subtitle, &got_output); } static int send_filter_eof(InputStream *ist) @@ -493,9 +499,13 @@ static int send_filter_eof(InputStream *ist) int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof) { +AVCodecContext *dec = ist->dec_ctx; AVPacket *avpkt = ist->pkt; int ret, repeating = 0; +if (dec->codec_type == AVMEDIA_TYPE_SUBTITLE) +return transcode_subtitles(ist, pkt ? pkt : ist->pkt); + if (pkt) { av_packet_unref(avpkt); ret = av_packet_ref(avpkt, pkt); @@ -520,14 +530,6 @@ int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof) av_packet_unref(avpkt); break; -case AVMEDIA_TYPE_SUBTITLE: -if (repeating) -break; -ret = transcode_subtitles(ist, avpkt, &got_output, &decode_failed); -if (!pkt && ret >= 0) -ret = AVERROR_EOF; -av_packet_unref(avpkt); -break; default: av_assert0(0); } -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 33/36] fftools/ffmpeg_dec: merge check_decode_result() into its callers
Not only is this easier to read, this also makes the code shorter. --- fftools/ffmpeg_dec.c | 32 +--- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c index 58bb7a7344..79e9c04fc1 100644 --- a/fftools/ffmpeg_dec.c +++ b/fftools/ffmpeg_dec.c @@ -31,24 +31,6 @@ #include "ffmpeg.h" -static void check_decode_result(InputStream *ist, int got_output, int ret) -{ -if (ret < 0) -ist->decode_errors++; - -if (ret < 0 && exit_on_error) -exit_program(1); - -if (got_output && ist->dec_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE) { -if (ist->decoded_frame->decode_error_flags || (ist->decoded_frame->flags & AV_FRAME_FLAG_CORRUPT)) { -av_log(ist, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING, - "corrupt decoded frame\n"); -if (exit_on_error) -exit_program(1); -} -} -} - static int send_frame_to_filters(InputStream *ist, AVFrame *decoded_frame) { int i, ret; @@ -385,10 +367,9 @@ static int transcode_subtitles(InputStream *ist, const AVPacket *pkt) av_err2str(ret)); if (exit_on_error) exit_program(1); +ist->decode_errors++; } -check_decode_result(ist, got_output, ret); - if (ret < 0 || !got_output) { if (!pkt->size) sub2video_flush(ist); @@ -448,9 +429,6 @@ int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof) update_benchmark("decode_%s %d.%d", type_desc, ist->file_index, ist->st->index); -if (ret != AVERROR_EOF && ret != AVERROR(EAGAIN)) -check_decode_result(ist, ret >= 0, ret); - if (ret == AVERROR(EAGAIN)) { av_assert0(pkt); // should never happen during flushing return 0; @@ -470,9 +448,17 @@ int dec_packet(InputStream *ist, const AVPacket *pkt, int no_eof) av_log(ist, AV_LOG_ERROR, "Decoding error: %s\n", av_err2str(ret)); if (exit_on_error) exit_program(1); +ist->decode_errors++; return ret; } +if (frame->decode_error_flags || (frame->flags & AV_FRAME_FLAG_CORRUPT)) { +av_log(ist, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING, + "corrupt decoded frame\n"); +if (exit_on_error) +exit_program(1); +} + if (ist->want_frame_data) { FrameData *fd; -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 1/1] fate/jpg: add RGB mjpeg fate tests
Am 16.05.23 um 16:41 schrieb Leo Izen: Adds FATE tests for RGB jpegs to test commit 0b352e350e773673f11ea380f3507923c70e1175. --- tests/fate/image.mak | 11 +++ tests/ref/fate/jpg-rgb-1 | 6 ++ tests/ref/fate/jpg-rgb-2 | 6 ++ tests/ref/fate/jpg-rgb-3 | 6 ++ tests/ref/fate/jpg-rgb-4 | 6 ++ tests/ref/fate/jpg-rgb-5 | 6 ++ 6 files changed, 41 insertions(+) create mode 100644 tests/ref/fate/jpg-rgb-1 create mode 100644 tests/ref/fate/jpg-rgb-2 create mode 100644 tests/ref/fate/jpg-rgb-3 create mode 100644 tests/ref/fate/jpg-rgb-4 create mode 100644 tests/ref/fate/jpg-rgb-5 Pushed, thanks! -Thilo ___ 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] doc/ffmpeg: Extend documentation for sws_flags option
Clarify that -sws_flags are only applied to simple filtergraphs as a default, not complex filtergraphs. Add a reference to the scaler options. --- doc/ffmpeg.texi | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index a12700e..c0fa90f 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -1023,7 +1023,12 @@ If @var{pix_fmt} is a single @code{+}, ffmpeg selects the same pixel format as the input (or graph output) and automatic conversions are disabled. @item -sws_flags @var{flags} (@emph{input/output}) -Set SwScaler flags. +Set default flags for the libswscale library. These flags are used by +automatically inserted @code{scale} filters and those within simple +filtergraphs, if not overridden within the filtergraph definition. + +See the @ref{scaler_options,,ffmpeg-scaler manual,ffmpeg-scaler} for a list +of scaler options. @item -rc_override[:@var{stream_specifier}] @var{override} (@emph{output,per-stream}) Rate control override for specific intervals, formatted as "int,int,int" -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/2, v3] amfenc: Update the min version to 1.4.29.0 for AMF SDK.
--- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index bb7be67676..937be943a4 100755 --- a/configure +++ b/configure @@ -7082,7 +7082,7 @@ fi enabled amf && check_cpp_condition amf "AMF/core/Version.h" \ -"(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x00010004001c" +"(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x00010004001d" # Funny iconv installations are not unusual, so check it after all flags have been set if enabled libc_iconv; then -- 2.38.1.windows.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 2/2, v3] libavcodec/amfenc: add PreAnalysis support
Additional information about the work of preanalysis can be found here: https://github.com/GPUOpen-LibrariesAndSDKs/AMF/wiki/PreProcessing%20and%20PreAnalysis --- libavcodec/amfenc.c | 101 +++-- libavcodec/amfenc.h | 27 +- libavcodec/amfenc_av1.c | 133 ++-- libavcodec/amfenc_h264.c | 187 ++- libavcodec/amfenc_hevc.c | 144 +++--- 5 files changed, 503 insertions(+), 89 deletions(-) diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c index c487fc48aa..cb48f8c273 100644 --- a/libavcodec/amfenc.c +++ b/libavcodec/amfenc.c @@ -481,7 +481,7 @@ static int amf_copy_buffer(AVCodecContext *avctx, AVPacket *pkt, AMFBuffer *buff AVERROR_UNKNOWN, "timestamp_list is empty\n"); // calc dts shift if max_b_frames > 0 -if (avctx->max_b_frames > 0 && ctx->dts_delay == 0) { +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); @@ -593,6 +593,8 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) AMFData*data = NULL; AVFrame*frame = ctx->delayed_frame; int block_and_wait; +int query_output_data_flag = 0; +AMF_RESULT res_resubmit; if (!ctx->encoder) return AVERROR(EINVAL); @@ -715,56 +717,61 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) do { block_and_wait = 0; // poll data -res_query = ctx->encoder->pVtbl->QueryOutput(ctx->encoder, &data); -if (data) { -// copy data to packet -AMFBuffer* buffer; -AMFGuid guid = IID_AMFBuffer(); -data->pVtbl->QueryInterface(data, &guid, (void**)&buffer); // query for buffer interface -ret = amf_copy_buffer(avctx, avpkt, buffer); - -buffer->pVtbl->Release(buffer); - -if (data->pVtbl->HasProperty(data, L"av_frame_ref")) { -AMFBuffer *frame_ref_storage_buffer; -res = amf_get_property_buffer(data, L"av_frame_ref", &frame_ref_storage_buffer); -AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "GetProperty failed for \"av_frame_ref\" with error %d\n", res); -amf_release_buffer_with_frame_ref(frame_ref_storage_buffer); -ctx->hwsurfaces_in_queue--; -} - -data->pVtbl->Release(data); +if (!avpkt->data && !avpkt->buf) { +res_query = ctx->encoder->pVtbl->QueryOutput(ctx->encoder, &data); +if (data) { +query_output_data_flag = 1; +// copy data to packet +AMFBuffer *buffer; +AMFGuid guid = IID_AMFBuffer(); +data->pVtbl->QueryInterface(data, &guid, (void**)&buffer); // query for buffer interface +ret = amf_copy_buffer(avctx, avpkt, buffer); + +buffer->pVtbl->Release(buffer); + +if (data->pVtbl->HasProperty(data, L"av_frame_ref")) { +AMFBuffer* frame_ref_storage_buffer; +res = amf_get_property_buffer(data, L"av_frame_ref", &frame_ref_storage_buffer); +AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "GetProperty failed for \"av_frame_ref\" with error %d\n", res); + amf_release_buffer_with_frame_ref(frame_ref_storage_buffer); +ctx->hwsurfaces_in_queue--; +} -AMF_RETURN_IF_FALSE(ctx, ret >= 0, ret, "amf_copy_buffer() failed with error %d\n", ret); +data->pVtbl->Release(data); -if (ctx->delayed_surface != NULL) { // try to resubmit frame -res = ctx->encoder->pVtbl->SubmitInput(ctx->encoder, (AMFData*)ctx->delayed_surface); -if (res != AMF_INPUT_FULL) { -int64_t pts = ctx->delayed_surface->pVtbl->GetPts(ctx->delayed_surface); -ctx->delayed_surface->pVtbl->Release(ctx->delayed_surface); -ctx->delayed_surface = NULL; -av_frame_unref(ctx->delayed_frame); -AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "Repeated SubmitInput() failed with error %d\n", res); +AMF_RETURN_IF_FALSE(ctx, ret >= 0, ret, "amf_copy_buffer() failed with error %d\n", ret); +} +} +res_resubmit = AMF_OK; +if (ctx->delayed_surface != NULL) { // try to resubmit frame +res_resubmit = ctx->encoder->pVtbl->SubmitInput(ctx->encoder, (AMFData*)ctx->delayed_surface); +if (res_resubmit != AMF_INPUT_FULL) { +int64_t pts = ctx->delayed_surface->pVtbl->GetPts(ctx->delayed_surface); +ctx->delayed_surface->pVtbl->Rel
Re: [FFmpeg-devel] [REFUND-REQUEST] Travel cost & more for CLT 2023
On Wed, May 10, 2023 at 03:36:17AM +0200, Thomas Volkert wrote: > Hi, > > > Am 15.03.2023 um 20:30 schrieb Thilo Borgmann: > > > > > for our recent appearance at the Chemnitzer Linux Tage, I'd like to > > request reimbursements for my travel cost. > > I picked up Carl-Eugen in Berlin and we drove to Chemnitz together > > (~560 km in total). > > All hotel costs and further costs for merch and the webcam were > > preliminarily covered by others. > > > > So for me, it is just > > > > 61,40 EUR for Gas. > > > > Thanks, > > Thilo > > > I would like to add my expenses to this list: > > 1. hotel: 318 > 2. merch: t-shirts, polo-shirts, sweatshirts 876,08 > 3. transport: gas 79,41 + 79,94 + 39,80 + 69,97 > = 269,12 > 4. equipment: webcam 4K multi remote control 79,99 > --- > => total: 1543,19 Euro > > Details: > 1. We booked the same hotel suite during the weekend (Thilo Borgmann, Carl > Eugen Hoyos, Alexander Strasser & me) as we did in the past. > 2. After the old merch. box was almost empty and no shirts were left, we > ordered new ones. The amount was planned to be enough for the next couple of > years. All remaining shirts are with Thilo since he plans to go to Linux Days > 2023 in Prague, Czech Republic, in October this year - I won't attend. > 3. I transported my equipment and the box with 50 merch. shirts. > 4. After we discussed this step several years, this time we decided to > finally buy a new one and use it for the demo setup. The camera is with Thilo > - see point 2. LGTM thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Modern terrorism, a quick summary: Need oil, start war with country that has oil, kill hundread thousand in war. Let country fall into chaos, be surprised about raise of fundamantalists. Drop more bombs, kill more people, be surprised about them taking revenge and drop even more bombs and strip your own citizens of their rights and freedoms. to be continued 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] doc/ffmpeg: Extend documentation for sws_flags option
On 2023-05-17 05:22 pm, Tobias Rapp wrote: Clarify that -sws_flags are only applied to simple filtergraphs as a default, not complex filtergraphs. Add a reference to the scaler options. LGTM Regards, Gyan --- doc/ffmpeg.texi | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index a12700e..c0fa90f 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -1023,7 +1023,12 @@ If @var{pix_fmt} is a single @code{+}, ffmpeg selects the same pixel format as the input (or graph output) and automatic conversions are disabled. @item -sws_flags @var{flags} (@emph{input/output}) -Set SwScaler flags. +Set default flags for the libswscale library. These flags are used by +automatically inserted @code{scale} filters and those within simple +filtergraphs, if not overridden within the filtergraph definition. + +See the @ref{scaler_options,,ffmpeg-scaler manual,ffmpeg-scaler} for a list +of scaler options. @item -rc_override[:@var{stream_specifier}] @var{override} (@emph{output,per-stream}) Rate control override for specific intervals, formatted as "int,int,int" ___ 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/6] avcodec/filter_units_bsf: add skip frame support
From: Zhao Zhili --- libavcodec/filter_units_bsf.c | 42 +-- libavcodec/version.h | 2 +- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/libavcodec/filter_units_bsf.c b/libavcodec/filter_units_bsf.c index 38756baf42..e4c2cadbd5 100644 --- a/libavcodec/filter_units_bsf.c +++ b/libavcodec/filter_units_bsf.c @@ -34,6 +34,8 @@ typedef struct FilterUnitsContext { const char *pass_types; const char *remove_types; +enum AVDiscard discard; +int discard_flags; enum { NOOP, @@ -109,7 +111,7 @@ static int filter_units_filter(AVBSFContext *bsf, AVPacket *pkt) if (err < 0) return err; -if (ctx->mode == NOOP) +if (ctx->mode == NOOP && ctx->discard <= AVDISCARD_DEFAULT) return 0; err = ff_cbs_read_packet(ctx->cbc, frag, pkt); @@ -118,6 +120,8 @@ static int filter_units_filter(AVBSFContext *bsf, AVPacket *pkt) goto fail; } +ff_cbs_discard_units(ctx->cbc, frag, ctx->discard, ctx->discard_flags); +if (ctx->mode != NOOP) { for (i = frag->nb_units - 1; i >= 0; i--) { for (j = 0; j < ctx->nb_types; j++) { if (frag->units[i].type == ctx->type_list[j]) @@ -127,6 +131,7 @@ static int filter_units_filter(AVBSFContext *bsf, AVPacket *pkt) : j >= ctx->nb_types) ff_cbs_delete_unit(frag, i); } +} if (frag->nb_units == 0) { // Don't return packets with nothing in them. @@ -175,7 +180,7 @@ static int filter_units_init(AVBSFContext *bsf) av_log(bsf, AV_LOG_ERROR, "Failed to parse remove_types.\n"); return err; } -} else { +} else if (ctx->discard == AVDISCARD_NONE) { return 0; } @@ -183,9 +188,11 @@ static int filter_units_init(AVBSFContext *bsf) if (err < 0) return err; +if (ctx->discard == AVDISCARD_NONE) { // Don't actually decompose anything, we only want the unit data. ctx->cbc->decompose_unit_types= ctx->type_list; ctx->cbc->nb_decompose_unit_types = 0; +} if (bsf->par_in->extradata) { CodedBitstreamFragment *frag = &ctx->fragment; @@ -225,6 +232,37 @@ static const AVOption filter_units_options[] = { OFFSET(remove_types), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS }, +{ "discard", "Remove the selected frames", +OFFSET(discard), AV_OPT_TYPE_INT, +{ .i64 = AVDISCARD_NONE }, INT_MIN, INT_MAX, FLAGS, "discard"}, +{ "none" , "discard none", +0, AV_OPT_TYPE_CONST, +{ .i64 = AVDISCARD_NONE }, INT_MIN, INT_MAX, FLAGS, "discard"}, +{ "default" , "discard none, but can be changed after dynamically", +0, AV_OPT_TYPE_CONST, +{ .i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, FLAGS, "discard"}, +{ "nonref", "discard all non-reference frames", +0, AV_OPT_TYPE_CONST, +{ .i64 = AVDISCARD_NONREF }, INT_MIN, INT_MAX, FLAGS, "discard"}, +{ "bidir", "discard all bidirectional frames", +0, AV_OPT_TYPE_CONST, +{ .i64 = AVDISCARD_BIDIR }, INT_MIN, INT_MAX, FLAGS, "discard"}, +{ "nonintra", "discard all frames except I frames", +0, AV_OPT_TYPE_CONST, +{ .i64 = AVDISCARD_NONINTRA }, INT_MIN, INT_MAX, FLAGS, "discard"}, +{ "nonkey", "discard all frames except keyframes", +0, AV_OPT_TYPE_CONST, +{ .i64 = AVDISCARD_NONKEY }, INT_MIN, INT_MAX, FLAGS, "discard"}, +{ "all", "discard all frames", +0, AV_OPT_TYPE_CONST, +{ .i64 = AVDISCARD_ALL }, INT_MIN, INT_MAX, FLAGS, "discard"}, + +{ "discard_flags", "flags to control the discard frame behavior", +OFFSET(discard_flags), AV_OPT_TYPE_FLAGS, +{ .i64 = DISCARD_FLAG_NONE }, INT_MIN, INT_MAX, FLAGS, "discard_flags"}, +{ "keep_non_vcl", "non-vcl units even if the picture has been dropped", +0, AV_OPT_TYPE_CONST, +{ .i64 = DISCARD_FLAG_KEEP_NON_VCL }, INT_MIN, INT_MAX, FLAGS, "discard_flags"}, { NULL } }; diff --git a/libavcodec/version.h b/libavcodec/version.h index 7531c6c42a..c20072197d 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -30,7 +30,7 @@ #include "version_major.h" #define LIBAVCODEC_VERSION_MINOR 14 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ -- 2.25.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 3/6] avcodec/cbs_h2645: add discard_unit implementation for H.265
From: Zhao Zhili --- libavcodec/cbs_h2645.c | 74 ++ 1 file changed, 74 insertions(+) diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index c616ac2202..f2e59f1ac7 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -1265,6 +1265,79 @@ static int cbs_h264_discarded_nal_unit(CodedBitstreamContext *ctx, return 0; } +static int cbs_h265_discarded_nal_unit(CodedBitstreamContext *ctx, + const CodedBitstreamUnit *unit, + enum AVDiscard skip) +{ +H265RawSliceHeader *slice; + +if (skip <= AVDISCARD_DEFAULT) +return 0; + +switch (unit->type) { +case HEVC_NAL_BLA_W_LP: +case HEVC_NAL_BLA_W_RADL: +case HEVC_NAL_BLA_N_LP: +case HEVC_NAL_IDR_W_RADL: +case HEVC_NAL_IDR_N_LP: +case HEVC_NAL_CRA_NUT: +// IRAP slice +if (skip < AVDISCARD_ALL) +return 0; +break; + +case HEVC_NAL_TRAIL_R: +case HEVC_NAL_TRAIL_N: +case HEVC_NAL_TSA_N: +case HEVC_NAL_TSA_R: +case HEVC_NAL_STSA_N: +case HEVC_NAL_STSA_R: +case HEVC_NAL_RADL_N: +case HEVC_NAL_RADL_R: +case HEVC_NAL_RASL_N: +case HEVC_NAL_RASL_R: +// Slice +break; +default: +// Don't discard non-slice nal. +return 0; +} + +if (skip >= AVDISCARD_NONKEY) +return 1; + +slice = (H265RawSliceHeader *)unit->content; +if (!slice) { +av_log(ctx->log_ctx, AV_LOG_WARNING, +"h265 slice header is null, missing decompose?\n"); +return 0; +} + +if (skip >= AVDISCARD_NONINTRA && slice->slice_type != HEVC_SLICE_I) +return 1; +if (skip >= AVDISCARD_BIDIR && slice->slice_type == HEVC_SLICE_B) +return 1; + +if (skip >= AVDISCARD_NONREF) { +switch (unit->type) { +case HEVC_NAL_TRAIL_N: +case HEVC_NAL_TSA_N: +case HEVC_NAL_STSA_N: +case HEVC_NAL_RADL_N: +case HEVC_NAL_RASL_N: +case HEVC_NAL_VCL_N10: +case HEVC_NAL_VCL_N12: +case HEVC_NAL_VCL_N14: +// non-ref +return 1; +default: +break; +} +} + +return 0; +} + static int cbs_h2645_unit_requires_zero_byte(enum AVCodecID codec_id, CodedBitstreamUnitType type, int nal_unit_index) @@ -1510,6 +1583,7 @@ const CodedBitstreamType ff_cbs_type_h265 = { .split_fragment= &cbs_h2645_split_fragment, .read_unit = &cbs_h265_read_nal_unit, .write_unit= &cbs_h265_write_nal_unit, +.discarded_unit= &cbs_h265_discarded_nal_unit, .assemble_fragment = &cbs_h2645_assemble_fragment, .flush = &cbs_h265_flush, -- 2.25.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 1/6] avcodec/cbs: add API to discard units by AVDiscard
From: Zhao Zhili --- libavcodec/cbs.c | 21 + libavcodec/cbs.h | 17 + libavcodec/cbs_internal.h | 6 ++ 3 files changed, 44 insertions(+) diff --git a/libavcodec/cbs.c b/libavcodec/cbs.c index 504197e06d..cf5211249b 100644 --- a/libavcodec/cbs.c +++ b/libavcodec/cbs.c @@ -1026,3 +1026,24 @@ int ff_cbs_make_unit_writable(CodedBitstreamContext *ctx, av_buffer_unref(&ref); return 0; } + +void ff_cbs_discard_units(CodedBitstreamContext *ctx, + CodedBitstreamFragment *frag, + enum AVDiscard skip, + int flags) +{ +if (!ctx->codec->discarded_unit) +return; + +for (int i = frag->nb_units - 1; i >= 0; i--) { +if (ctx->codec->discarded_unit(ctx, &frag->units[i], skip)) { +// discard all units +if (!(flags & DISCARD_FLAG_KEEP_NON_VCL)) { +ff_cbs_fragment_free(frag); +return; +} + +ff_cbs_delete_unit(frag, i); +} +} +} diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h index ee21623dac..b4131db5fe 100644 --- a/libavcodec/cbs.h +++ b/libavcodec/cbs.h @@ -26,6 +26,7 @@ #include "codec_id.h" #include "codec_par.h" +#include "defs.h" #include "packet.h" @@ -432,5 +433,21 @@ int ff_cbs_make_unit_refcounted(CodedBitstreamContext *ctx, int ff_cbs_make_unit_writable(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit); +enum CbsDiscardFlags { +DISCARD_FLAG_NONE = 0, + +/** + * keep non-vcl units even if the picture has been dropped. + */ +DISCARD_FLAG_KEEP_NON_VCL = 0x01, +}; + +/** + * Discard units accroding to 'skip'. + */ +void ff_cbs_discard_units(CodedBitstreamContext *ctx, + CodedBitstreamFragment *frag, + enum AVDiscard skip, + int flags); #endif /* AVCODEC_CBS_H */ diff --git a/libavcodec/cbs_internal.h b/libavcodec/cbs_internal.h index e585c77934..077954eee5 100644 --- a/libavcodec/cbs_internal.h +++ b/libavcodec/cbs_internal.h @@ -133,6 +133,12 @@ typedef struct CodedBitstreamType { CodedBitstreamUnit *unit, PutBitContext *pbc); +// Return 1 when the unit should be dropped according to 'skip', +// 0 otherwise. +int (*discarded_unit)(CodedBitstreamContext *ctx, + const CodedBitstreamUnit *unit, + enum AVDiscard skip); + // Read the data from all of frag->units and assemble it into // a bitstream for the whole fragment. int (*assemble_fragment)(CodedBitstreamContext *ctx, -- 2.25.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 5/6] avcodec/filter_units_bsf: reindent after previous commit
From: Zhao Zhili --- libavcodec/filter_units_bsf.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/libavcodec/filter_units_bsf.c b/libavcodec/filter_units_bsf.c index e4c2cadbd5..9336753148 100644 --- a/libavcodec/filter_units_bsf.c +++ b/libavcodec/filter_units_bsf.c @@ -122,15 +122,15 @@ static int filter_units_filter(AVBSFContext *bsf, AVPacket *pkt) ff_cbs_discard_units(ctx->cbc, frag, ctx->discard, ctx->discard_flags); if (ctx->mode != NOOP) { -for (i = frag->nb_units - 1; i >= 0; i--) { -for (j = 0; j < ctx->nb_types; j++) { -if (frag->units[i].type == ctx->type_list[j]) -break; +for (i = frag->nb_units - 1; i >= 0; i--) { +for (j = 0; j < ctx->nb_types; j++) { +if (frag->units[i].type == ctx->type_list[j]) +break; +} +if (ctx->mode == REMOVE ? j < ctx->nb_types +: j >= ctx->nb_types) +ff_cbs_delete_unit(frag, i); } -if (ctx->mode == REMOVE ? j < ctx->nb_types -: j >= ctx->nb_types) -ff_cbs_delete_unit(frag, i); -} } if (frag->nb_units == 0) { @@ -189,9 +189,9 @@ static int filter_units_init(AVBSFContext *bsf) return err; if (ctx->discard == AVDISCARD_NONE) { -// Don't actually decompose anything, we only want the unit data. -ctx->cbc->decompose_unit_types= ctx->type_list; -ctx->cbc->nb_decompose_unit_types = 0; +// Don't actually decompose anything, we only want the unit data. +ctx->cbc->decompose_unit_types= ctx->type_list; +ctx->cbc->nb_decompose_unit_types = 0; } if (bsf->par_in->extradata) { -- 2.25.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 2/6] avcodec/cbs_h2645: add discarded_unit implementation for H.264
From: Zhao Zhili --- libavcodec/cbs_h2645.c | 53 ++ 1 file changed, 53 insertions(+) diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index 80e48829af..c616ac2202 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -1213,6 +1213,58 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx, return 0; } +static int cbs_h264_discarded_nal_unit(CodedBitstreamContext *ctx, + const CodedBitstreamUnit *unit, + enum AVDiscard skip) +{ +H264RawNALUnitHeader *header; +H264RawSliceHeader *slice; +int slice_type_i, slice_type_b, slice_type_si; + +if (skip <= AVDISCARD_DEFAULT) +return 0; + +// keep non-VCL +if (unit->type != H264_NAL_SLICE && +unit->type != H264_NAL_IDR_SLICE && +unit->type != H264_NAL_AUXILIARY_SLICE) +return 0; + +if (skip >= AVDISCARD_ALL) +return 1; + +if (skip >= AVDISCARD_NONKEY && unit->type != H264_NAL_IDR_SLICE) +return 1; + +header = (H264RawNALUnitHeader *)unit->content; +if (!header) { +av_log(ctx->log_ctx, AV_LOG_WARNING, +"h264 nal unit header is null, missing decompose?\n"); +return 0; +} + +if (skip >= AVDISCARD_NONREF && !header->nal_ref_idc) +return 1; + +slice = (H264RawSliceHeader *)unit->content; +if (!slice) { +av_log(ctx->log_ctx, AV_LOG_WARNING, +"h264 slice header is null, missing decompose?\n"); +return 0; +} + +slice_type_i = slice->slice_type % 5 == 2; +slice_type_b = slice->slice_type % 5 == 1; +slice_type_si = slice->slice_type % 5 == 4; + +if (skip >= AVDISCARD_BIDIR && slice_type_b) +return 1; +if (skip >= AVDISCARD_NONINTRA && !slice_type_i && !slice_type_si) +return 1; + +return 0; +} + static int cbs_h2645_unit_requires_zero_byte(enum AVCodecID codec_id, CodedBitstreamUnitType type, int nal_unit_index) @@ -1441,6 +1493,7 @@ const CodedBitstreamType ff_cbs_type_h264 = { .split_fragment= &cbs_h2645_split_fragment, .read_unit = &cbs_h264_read_nal_unit, .write_unit= &cbs_h264_write_nal_unit, +.discarded_unit= &cbs_h264_discarded_nal_unit, .assemble_fragment = &cbs_h2645_assemble_fragment, .flush = &cbs_h264_flush, -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 6/6] fate/cbs: add tests for discard_units
From: Zhao Zhili --- tests/fate/cbs.mak | 28 ++ tests/ref/fate/cbs-h264-discard-bidir| 37 + tests/ref/fate/cbs-h264-discard-nonintra | 8 +++ tests/ref/fate/cbs-h264-discard-nonkey | 3 ++ tests/ref/fate/cbs-h264-discard-nonref | 67 tests/ref/fate/cbs-hevc-discard-bidir| 3 ++ tests/ref/fate/cbs-hevc-discard-nonintra | 3 ++ tests/ref/fate/cbs-hevc-discard-nonkey | 3 ++ tests/ref/fate/cbs-hevc-discard-nonref | 26 + 9 files changed, 178 insertions(+) create mode 100644 tests/ref/fate/cbs-h264-discard-bidir create mode 100644 tests/ref/fate/cbs-h264-discard-nonintra create mode 100644 tests/ref/fate/cbs-h264-discard-nonkey create mode 100644 tests/ref/fate/cbs-h264-discard-nonref create mode 100644 tests/ref/fate/cbs-hevc-discard-bidir create mode 100644 tests/ref/fate/cbs-hevc-discard-nonintra create mode 100644 tests/ref/fate/cbs-hevc-discard-nonkey create mode 100644 tests/ref/fate/cbs-hevc-discard-nonref diff --git a/tests/fate/cbs.mak b/tests/fate/cbs.mak index a93e58ea9f..3d1ccf3897 100644 --- a/tests/fate/cbs.mak +++ b/tests/fate/cbs.mak @@ -12,6 +12,19 @@ FATE_CBS_$(1) += fate-cbs-$(1)-$(2) fate-cbs-$(1)-$(2): CMD = md5 -c:v $(3) -i $(TARGET_SAMPLES)/$(4) -c:v copy -y -bsf:v $(1)_metadata -f $(5) endef +define FATE_CBS_DISCARD_TEST +# (codec, discard_type, sample_file, output_format, dep) +FATE_CBS_$(1)_DISCARD += fate-cbs-$(1)-discard-$(2) + +tests/data/fate/cbs-$(1)-discard-$2.$(4): TAG = GEN +tests/data/fate/cbs-$(1)-discard-$2.$(4): ffmpeg$(PROGSSUF)$(EXESUF) $(5) | tests/data + $(M)$(TARGET_EXEC) $(TARGET_PATH)/ffmpeg$(PROGSSUF)$(EXESUF) -nostdin \ + -i $(3) -c:v copy -an -bsf:v filter_units=discard=$(2) \ + -f $(4) $(TARGET_PATH)/tests/data/fate/cbs-$(1)-discard-$(2).$(4) -y 2>/dev/null +fate-cbs-$(1)-discard-$2: ffprobe tests/data/fate/cbs-$(1)-discard-$(2).$(4) +fate-cbs-$(1)-discard-$2: CMD = ffprobe_demux $(TARGET_PATH)/tests/data/fate/cbs-$(1)-discard-$(2).$(4) +endef + # AV1 read/write FATE_CBS_AV1_CONFORMANCE_SAMPLES = \ @@ -67,6 +80,13 @@ $(foreach N,$(FATE_CBS_H264_SAMPLES),$(eval $(call FATE_CBS_TEST,h264,$(basename FATE_CBS_H264-$(call FATE_CBS_DEPS, H264, H264, H264, H264, H264) = $(FATE_CBS_h264) +$(eval $(call FATE_CBS_DISCARD_TEST,h264,nonref,$(TARGET_SAMPLES)/h264/interlaced_crop.mp4,mp4)) +$(eval $(call FATE_CBS_DISCARD_TEST,h264,bidir,$(TARGET_SAMPLES)/h264/interlaced_crop.mp4,mp4)) +$(eval $(call FATE_CBS_DISCARD_TEST,h264,nonintra,$(TARGET_SAMPLES)/h264/interlaced_crop.mp4,mp4)) +$(eval $(call FATE_CBS_DISCARD_TEST,h264,nonkey,$(TARGET_SAMPLES)/h264/interlaced_crop.mp4,mp4)) + +FATE_CBS_H264-$(call ALLYES, MP4_MUXER, H264_PARSER, FILTER_UNITS_BSF, H264_MUXER) += $(FATE_CBS_h264_DISCARD) + FATE_H264_REDUNDANT_PPS-$(call REMUX, H264, MOV_DEMUXER H264_REDUNDANT_PPS_BSF \ H264_DECODER H264_PARSER RAWVIDEO_ENCODER) \ @@ -133,6 +153,14 @@ FATE_CBS_HEVC_SAMPLES = \ $(foreach N,$(FATE_CBS_HEVC_SAMPLES),$(eval $(call FATE_CBS_TEST,hevc,$(basename $(N)),hevc,hevc-conformance/$(N),hevc))) FATE_CBS_HEVC-$(call FATE_CBS_DEPS, HEVC, HEVC, HEVC, HEVC, HEVC) = $(FATE_CBS_hevc) + +$(eval $(call FATE_CBS_DISCARD_TEST,hevc,nonref,$(TARGET_PATH)/tests/data/hevc-mp4.mov,mp4,tests/data/hevc-mp4.mov)) +$(eval $(call FATE_CBS_DISCARD_TEST,hevc,bidir,$(TARGET_PATH)/tests/data/hevc-mp4.mov,mp4,tests/data/hevc-mp4.mov)) +$(eval $(call FATE_CBS_DISCARD_TEST,hevc,nonintra,$(TARGET_PATH)/tests/data/hevc-mp4.mov,mp4,tests/data/hevc-mp4.mov)) +$(eval $(call FATE_CBS_DISCARD_TEST,hevc,nonkey,$(TARGET_PATH)/tests/data/hevc-mp4.mov,mp4,tests/data/hevc-mp4.mov)) + +FATE_CBS_HEVC-$(call ALLYES, MP4_MUXER, HEVC_PARSER, FILTER_UNITS_BSF, HEVC_MUXER) += $(FATE_CBS_hevc_DISCARD) + FATE_SAMPLES_AVCONV += $(FATE_CBS_HEVC-yes) fate-cbs-hevc: $(FATE_CBS_HEVC-yes) diff --git a/tests/ref/fate/cbs-h264-discard-bidir b/tests/ref/fate/cbs-h264-discard-bidir new file mode 100644 index 00..f161ee392c --- /dev/null +++ b/tests/ref/fate/cbs-h264-discard-bidir @@ -0,0 +1,37 @@ +packet|codec_type=video|stream_index=0|pts=0|pts_time=0.00|dts=-1024|dts_time=-0.08|duration=512|duration_time=0.04|size=22583|pos=48|flags=K__|data_hash=CRC32:69e4d65d +packet|codec_type=video|stream_index=0|pts=2048|pts_time=0.16|dts=-512|dts_time=-0.04|duration=512|duration_time=0.04|size=4023|pos=22631|flags=___|data_hash=CRC32:0013cf12 +packet|codec_type=video|stream_index=0|pts=4096|pts_time=0.32|dts=1536|dts_time=0.12|duration=512|duration_time=0.04|size=4214|pos=26654|flags=___|data_hash=CRC32:3d1a75de +packet|codec_type=video|stream_index=0|pts=6144|pts_time=0.48|dts=3584|dts_time=0.28|duration=512|duration_time=0.04|size=4067|pos=30868|flags=___|data_hash=CRC32:0ae6ba93 +packet|codec_type=video|stream_index=0|pts=8192|pts_time=0.64|dts=5632|dts_time=0.44|d
[FFmpeg-devel] [PATCH] avformat/yuvmpegenc: add support for rawvideo input
The demuxer exports rawvideo, so there's no reason for the muxer to only work with wrapped_avframe. Signed-off-by: James Almer --- libavformat/yuv4mpegenc.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libavformat/yuv4mpegenc.c b/libavformat/yuv4mpegenc.c index 2fa5ee2714..968ba2fa13 100644 --- a/libavformat/yuv4mpegenc.c +++ b/libavformat/yuv4mpegenc.c @@ -189,6 +189,11 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt) avio_printf(s->pb, Y4M_FRAME_MAGIC "\n"); +if (st->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO) { +avio_write(pb, pkt->data, pkt->size); +return 0; +} + width = st->codecpar->width; height = st->codecpar->height; desc = av_pix_fmt_desc_get(st->codecpar->format); @@ -218,7 +223,8 @@ static int yuv4_init(AVFormatContext *s) if (s->nb_streams != 1) return AVERROR(EIO); -if (s->streams[0]->codecpar->codec_id != AV_CODEC_ID_WRAPPED_AVFRAME) { +if (s->streams[0]->codecpar->codec_id != AV_CODEC_ID_WRAPPED_AVFRAME && +s->streams[0]->codecpar->codec_id != AV_CODEC_ID_RAWVIDEO) { av_log(s, AV_LOG_ERROR, "ERROR: Codec not supported.\n"); return AVERROR_INVALIDDATA; } -- 2.40.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] lavc/h264chroma: RISC-V V add motion compensation for 8x8 chroma blocks
May 17, 2023, 09:13 by arnie.ch...@sifive.com: > Optimize the put and avg filtering for 8x8 chroma blocks > > Signed-off-by: Arnie Chang > --- > libavcodec/h264chroma.c | 2 + > libavcodec/h264chroma.h | 1 + > libavcodec/riscv/Makefile | 3 + > libavcodec/riscv/h264_chroma_init_riscv.c | 39 ++ > libavcodec/riscv/h264_mc_chroma.S | 492 ++ > libavcodec/riscv/h264_mc_chroma.h | 34 ++ > 6 files changed, 571 insertions(+) > create mode 100644 libavcodec/riscv/h264_chroma_init_riscv.c > create mode 100644 libavcodec/riscv/h264_mc_chroma.S > create mode 100644 libavcodec/riscv/h264_mc_chroma.h > > +#include > + > +#include "libavutil/attributes.h" > +#include "libavutil/cpu.h" > +#include "libavcodec/h264chroma.h" > +#include "config.h" > +#include "h264_mc_chroma.h" > + > +av_cold void ff_h264chroma_init_riscv(H264ChromaContext *c, int bit_depth) > +{ > +#if HAVE_RVV > +const int high_bit_depth = bit_depth > 8; > You don't need this constant. > + > +if (!high_bit_depth) { > +c->put_h264_chroma_pixels_tab[0] = h264_put_chroma_mc8_rvv; > +c->avg_h264_chroma_pixels_tab[0] = h264_avg_chroma_mc8_rvv; > +} > +#endif > You have to check if RVV is supported: > int flags = av_get_cpu_flags(); > > if (flags & AV_CPU_FLAG_RVV_F32) { > if (bit_depth > 8) { > +.text > + > +.globlh264_put_chroma_mc8_rvv > +.p2align1 > +.typeh264_put_chroma_mc8_rvv,@function > +h264_put_chroma_mc8_rvv: > You don't need any of this. We already have macros to handle this - take a look at libavcodec/riscv/opusdsp_rvv.S: > func ff_opus_postfilter_rvv_256, zve32f > lvtypei a5, e32, m1, ta, ma // function instructions start here Make sure to change zve32f to whatever instruction extension you use to initialize the assembler to handle it. > +slliwt2, a5, 3 > +mulwt1, a5, a4 > +sh3adda5, a4, t2 > +slliwa4, a4, 3 > +subwa5, t1, a5 > +subwa7, a4, t1 > +addiwa6, a5, 64 > +subwt0, t2, t1 > Coding style issue - we style our RISC-V assembly the same way we style our AArch64 assembly: <8 spaces> For example: > vsetvl zero, a4, a5 > lw t2, 20(a1) > vfmul.vv v8, v24, v16 > addi a0, a0, 4 > vslide1down.vx v16, v16, t2 > MACRO arg1, arg2 > +.LBB0_8:# if ((x8 - xy) == 0 && (y8 -xy) != > 0) > +adda5, a1, a4 > +vsetvlizero, zero, e8, m1, ta, ma > +addiwt1, t1, 4 > +vle8.vv8, (a5) > +adda5, a5, a2 > +addt2, a5, a2 > +vwmulu.vxv10, v8, a6 > This branch looks very similar to > .LBB1_16: # the final else, none of the above > conditions are met > add a5, a1, a4 > vsetvli zero, zero, e8, m1, ta, ma > addiw t0, t0, 4 > vle8.v v8, (a5) > add a5, a5, a2 > add t1, a5, a2 > vwmulu.vx v10, v8, a6 Consider using a macro. In fact, a lot of the branches look similar to each other. Looking at other implementations, they only consider 3 possible variants, the same ones that the C function has. > +.sizeh264_avg_chroma_mc8_rvv, .Lfunc_end1-h264_avg_chroma_mc8_rvv > diff --git a/libavcodec/riscv/h264_mc_chroma.h > b/libavcodec/riscv/h264_mc_chroma.h > new file mode 100644 > index 00..cb350d0e4a > --- /dev/null > +++ b/libavcodec/riscv/h264_mc_chroma.h > @@ -0,0 +1,34 @@ > +/* > + * Copyright (c) 2023 SiFive, Inc. All rights reserved. > + * > + * 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 AVCODEC_RISCV_H264_MC_CHROMA_H > +#define AVCODEC_RISCV_H264_MC_CHROMA_H > +#include > +#include > +#include > +#include > +#include > +#include "config.h" > You don't need all of these includes. Just config.h and stdint.h would be enough. > +#if HAVE_RVV > +void h264_put_chroma_mc8_rvv(uint8_t *p_dst, const uint8_t *p_src, ptrdiff_t > stride, int h, int x, int y); > +void h264_avg_chroma_mc8_rvv(uint8_t *p_dst, const uint8_t *p_src, ptrdiff_t > stride, int h, int x, int y); > +#endif > +#endif > \ No ne
Re: [FFmpeg-devel] [PATCH] doc/ffmpeg: Extend documentation for sws_flags option
On 17/05/2023 15:15, Gyan Doshi wrote: On 2023-05-17 05:22 pm, Tobias Rapp wrote: Clarify that -sws_flags are only applied to simple filtergraphs as a default, not complex filtergraphs. Add a reference to the scaler options. LGTM Regards, Gyan Applied. Thanks for review, Tobias ___ 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] avcodec/hevc_ps: add proper bound checks around cm_ref_layer_id in colour_mapping_table.
From: Clement Lecigne Signed-off-by: Michael Niedermayer --- libavcodec/hevc_ps.c | 17 + 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index a55bced0f7..313ebef151 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -1374,9 +1374,14 @@ static void colour_mapping_octants(GetBitContext *gb, HEVCPPS *pps, int inp_dept } } -static void colour_mapping_table(GetBitContext *gb, HEVCPPS *pps) +static int colour_mapping_table(GetBitContext *gb, AVCodecContext *avctx, HEVCPPS *pps) { -pps->num_cm_ref_layers_minus1 = get_ue_golomb_long(gb); +pps->num_cm_ref_layers_minus1 = get_ue_golomb(gb); +if (pps->num_cm_ref_layers_minus1 >= 63U) { +av_log(avctx, AV_LOG_ERROR, + "num_cm_ref_layers_minus1 shall be in the range [0, 63].\n"); +return AVERROR_INVALIDDATA; +} for (int i = 0; i <= pps->num_cm_ref_layers_minus1; i++) pps->cm_ref_layer_id[i] = get_bits(gb, 6); @@ -1397,6 +1402,7 @@ static void colour_mapping_table(GetBitContext *gb, HEVCPPS *pps) } colour_mapping_octants(gb, pps, 0, 0, 0, 0, 1 << pps->cm_octant_depth); +return 0; } static int pps_multilayer_extension(GetBitContext *gb, AVCodecContext *avctx, @@ -1439,8 +1445,11 @@ static int pps_multilayer_extension(GetBitContext *gb, AVCodecContext *avctx, } pps->colour_mapping_enabled_flag = get_bits1(gb); -if (pps->colour_mapping_enabled_flag) -colour_mapping_table(gb, pps); +if (pps->colour_mapping_enabled_flag) { +int ret = colour_mapping_table(gb, avctx, pps); +if (ret < 0) +return ret; +} return 0; } -- 2.17.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] lavfi/vf_libplacebo: allow linking to shared library with dllimport
Address of dll imported variables can't be used for constant initialization in C language modes. --- libavfilter/vf_libplacebo.c | 39 - 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c index 94e49aa465..f26d0126be 100644 --- a/libavfilter/vf_libplacebo.c +++ b/libavfilter/vf_libplacebo.c @@ -56,23 +56,6 @@ enum { TONE_MAP_COUNT, }; -static const struct pl_tone_map_function * const tonemapping_funcs[TONE_MAP_COUNT] = { -[TONE_MAP_AUTO] = &pl_tone_map_auto, -[TONE_MAP_CLIP] = &pl_tone_map_clip, -#if PL_API_VER >= 246 -[TONE_MAP_ST2094_40] = &pl_tone_map_st2094_40, -[TONE_MAP_ST2094_10] = &pl_tone_map_st2094_10, -#endif -[TONE_MAP_BT2390]= &pl_tone_map_bt2390, -[TONE_MAP_BT2446A] = &pl_tone_map_bt2446a, -[TONE_MAP_SPLINE]= &pl_tone_map_spline, -[TONE_MAP_REINHARD] = &pl_tone_map_reinhard, -[TONE_MAP_MOBIUS]= &pl_tone_map_mobius, -[TONE_MAP_HABLE] = &pl_tone_map_hable, -[TONE_MAP_GAMMA] = &pl_tone_map_gamma, -[TONE_MAP_LINEAR]= &pl_tone_map_linear, -}; - static const char *const var_names[] = { "in_w", "iw", ///< width of the input video frame "in_h", "ih", ///< height of the input video frame @@ -269,6 +252,26 @@ static void pl_av_log(void *log_ctx, enum pl_log_level level, const char *msg) av_log(log_ctx, av_lev, "%s\n", msg); } +static const struct pl_tone_map_function *pl_get_tonemapping_func(int tm) { +switch (tm) { +case TONE_MAP_AUTO: return &pl_tone_map_auto; +case TONE_MAP_CLIP: return &pl_tone_map_clip; +#if PL_API_VER >= 246 +case TONE_MAP_ST2094_40: return &pl_tone_map_st2094_40; +case TONE_MAP_ST2094_10: return &pl_tone_map_st2094_10; +#endif +case TONE_MAP_BT2390: return &pl_tone_map_bt2390; +case TONE_MAP_BT2446A:return &pl_tone_map_bt2446a; +case TONE_MAP_SPLINE: return &pl_tone_map_spline; +case TONE_MAP_REINHARD: return &pl_tone_map_reinhard; +case TONE_MAP_MOBIUS: return &pl_tone_map_mobius; +case TONE_MAP_HABLE: return &pl_tone_map_hable; +case TONE_MAP_GAMMA: return &pl_tone_map_gamma; +case TONE_MAP_LINEAR: return &pl_tone_map_linear; +default: av_assert0(0); +} +} + static int parse_shader(AVFilterContext *avctx, const void *shader, size_t len) { LibplaceboContext *s = avctx->priv; @@ -365,7 +368,7 @@ static int update_settings(AVFilterContext *ctx) s->color_map_params = *pl_color_map_params( .intent = s->intent, .gamut_mode = gamut_mode, -.tone_mapping_function = tonemapping_funcs[s->tonemapping], +.tone_mapping_function = pl_get_tonemapping_func(s->tonemapping), .tone_mapping_param = s->tonemapping_param, .tone_mapping_mode = tonemapping_mode, .inverse_tone_mapping = s->inverse_tonemapping, -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 31/36] fftools/ffmpeg_dec: restructure audio/video decoding loop
On Wed, May 17, 2023 at 12:20:24PM +0200, Anton Khirnov wrote: > It currently emulates the long-removed > avcodec_decode_audio4/avcodec_decode_video2 APIs, which obfuscates the > actual decoding flow. Restructure the decoding calls so that they > naturally follow the new avcodec_send_packet()/avcodec_receive_frame() > design. > > This is not only significantly easier to read, but also shorter. with this: ./ffmpeg -y -threads:a 1 -i tickets/1208/702121h264-TTA.mkvtest82.mkv -bitexact -vn file1208.mp3 Both before and afterwards the output is empty and we see Finishing stream without any data written to it. Output file is empty, nothing was encoded after this patch while the output is not any better, now ffmpeg proclaims success with its return code just to be sure i try reading the output [mp3 @ 0x5635bab17900] Format mp3 detected only with low score of 1, misdetection possible! [mp3 @ 0x5635bab17900] Failed to read frame size: Could not seek to 1026. [in#0 @ 0x5635bab177c0] Error opening input: Invalid argument I dont think that convertion was successfull [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB I am the wisest man alive, for I know one thing, and that is that I know nothing. -- Socrates 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 31/36] fftools/ffmpeg_dec: restructure audio/video decoding loop
On Wed, May 17, 2023 at 10:04:09PM +0200, Michael Niedermayer wrote: > On Wed, May 17, 2023 at 12:20:24PM +0200, Anton Khirnov wrote: > > It currently emulates the long-removed > > avcodec_decode_audio4/avcodec_decode_video2 APIs, which obfuscates the > > actual decoding flow. Restructure the decoding calls so that they > > naturally follow the new avcodec_send_packet()/avcodec_receive_frame() > > design. > > > > This is not only significantly easier to read, but also shorter. > > with this: > ./ffmpeg -y -threads:a 1 -i tickets/1208/702121h264-TTA.mkvtest82.mkv > -bitexact -vn file1208.mp3 > > Both before and afterwards the output is empty and we see > > Finishing stream without any data written to it. > Output file is empty, nothing was encoded > > after this patch while the output is not any better, now ffmpeg proclaims > success with its return code > > just to be sure i try reading the output > > [mp3 @ 0x5635bab17900] Format mp3 detected only with low score of 1, > misdetection possible! > [mp3 @ 0x5635bab17900] Failed to read frame size: Could not seek to 1026. > [in#0 @ 0x5635bab177c0] Error opening input: Invalid argument > > I dont think that convertion was successfull fiel seems here: ffmpeg-bugs/trac/ticket1208/702121h264-TTA.mkvtest82.mkv [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB During times of universal deceit, telling the truth becomes a revolutionary act. -- George Orwell 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 30/36] fftools/ffmpeg_dec: deobfuscate subtitle decoding
On Wed, May 17, 2023 at 12:20:23PM +0200, Anton Khirnov wrote: > It is currently handled in the same loop as audio and video, but this > obscures the actual flow, because only one iteration is ever performed > for subtitles. > > Also, avoid a pointless packet reference. > --- > fftools/ffmpeg_dec.c | 34 ++ > 1 file changed, 18 insertions(+), 16 deletions(-) The following results in a really large file now: (i stoped it so maybe infinite loop) ./ffmpeg -f lavfi -i "movie=tickets/1332/Starship_Troopers.vob[out0+subcc]" -vn -map s -y eia608.srt [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB The bravest are surely those who have the clearest vision of what is before them, glory and danger alike, and yet notwithstanding go out to meet it. -- Thucydides 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] avcodec/hevc_ps: add proper bound checks around cm_ref_layer_id in colour_mapping_table.
On 5/17/2023 2:28 PM, Michael Niedermayer wrote: From: Clement Lecigne Signed-off-by: Michael Niedermayer --- libavcodec/hevc_ps.c | 17 + 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index a55bced0f7..313ebef151 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -1374,9 +1374,14 @@ static void colour_mapping_octants(GetBitContext *gb, HEVCPPS *pps, int inp_dept } } -static void colour_mapping_table(GetBitContext *gb, HEVCPPS *pps) +static int colour_mapping_table(GetBitContext *gb, AVCodecContext *avctx, HEVCPPS *pps) { -pps->num_cm_ref_layers_minus1 = get_ue_golomb_long(gb); +pps->num_cm_ref_layers_minus1 = get_ue_golomb(gb); +if (pps->num_cm_ref_layers_minus1 >= 63U) { +av_log(avctx, AV_LOG_ERROR, + "num_cm_ref_layers_minus1 shall be in the range [0, 63].\n"); The spec in section F.7.4.3.3.5 says 0..61, no 0..63. I'll amend this (and update the array in the struct while at it) and push. +return AVERROR_INVALIDDATA; +} for (int i = 0; i <= pps->num_cm_ref_layers_minus1; i++) pps->cm_ref_layer_id[i] = get_bits(gb, 6); @@ -1397,6 +1402,7 @@ static void colour_mapping_table(GetBitContext *gb, HEVCPPS *pps) } colour_mapping_octants(gb, pps, 0, 0, 0, 0, 1 << pps->cm_octant_depth); +return 0; } static int pps_multilayer_extension(GetBitContext *gb, AVCodecContext *avctx, @@ -1439,8 +1445,11 @@ static int pps_multilayer_extension(GetBitContext *gb, AVCodecContext *avctx, } pps->colour_mapping_enabled_flag = get_bits1(gb); -if (pps->colour_mapping_enabled_flag) -colour_mapping_table(gb, pps); +if (pps->colour_mapping_enabled_flag) { +int ret = colour_mapping_table(gb, avctx, pps); +if (ret < 0) +return ret; +} return 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 v2 1/4] cbs_av1: Add tracing headers for metadata types
On 23/02/2023 13:14, James Almer wrote: On 1/24/2023 7:46 PM, Mark Thompson wrote: Make it a little easier to interpret metadata in trace output. --- libavcodec/cbs_av1_syntax_template.c | 10 ++ 1 file changed, 10 insertions(+) ... Set LGTM. Set applied. (Apologies for the delay in getting back to this :) Thanks, - Mark ___ 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] avutil/frame: deprecate palette_has_changed
Not only this is information that relies on the concept of a sequence of frames, which is completely out of place as a field in AVFrame, but its usefulness is also very limited. Signed-off-by: James Almer --- doc/APIchanges | 3 +++ libavcodec/8bps.c | 13 - libavcodec/ansi.c | 8 libavcodec/bethsoftvideo.c | 4 libavcodec/bfi.c| 8 libavcodec/bintext.c| 4 libavcodec/bmvvideo.c | 4 libavcodec/brenderpix.c | 8 libavcodec/c93.c| 4 libavcodec/cdgraphics.c | 4 libavcodec/cdtoons.c| 4 libavcodec/cinepak.c| 9 - libavcodec/dds.c| 8 libavcodec/dfa.c| 4 libavcodec/dsicinvideo.c| 4 libavcodec/dxa.c| 4 libavcodec/flicvideo.c | 4 libavcodec/gemdec.c | 4 libavcodec/idcinvideo.c | 9 - libavcodec/imx.c| 8 libavcodec/interplayvideo.c | 9 - libavcodec/jvdec.c | 8 libavcodec/kmvc.c | 17 - libavcodec/mscc.c | 4 libavcodec/msrle.c | 9 - libavcodec/mss1.c | 4 libavcodec/msvideo1.c | 9 - libavcodec/pafvideo.c | 4 libavcodec/pictordec.c | 4 libavcodec/psd.c| 4 libavcodec/qdrw.c | 4 libavcodec/qpeg.c | 9 - libavcodec/qtrle.c | 9 - libavcodec/rawdec.c | 8 libavcodec/rscc.c | 9 - libavcodec/sga.c| 4 libavcodec/smacker.c| 4 libavcodec/smc.c| 9 - libavcodec/targa.c | 4 libavcodec/tiertexseqv.c| 4 libavcodec/tmv.c| 4 libavcodec/tscc.c | 4 libavcodec/vb.c | 4 libavcodec/vqavideo.c | 4 libavcodec/yop.c| 4 libavutil/frame.c | 4 libavutil/frame.h | 3 +++ libavutil/version.h | 1 + 48 files changed, 267 insertions(+), 15 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index d2255867a8..770d6ffc5e 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2023-02-09 API changes, most recent first: +2023-05-xx - xx - lavu 58 - frame.h + Deprecate AVFrame.palette_has_changed without replacement. + 2023-05-xx - xx - lavc 60 - avcodec.h Depreate AVCodecContext.ticks_per_frame in favor of AVCodecContext.framerate (encoding) and diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c index 90d6c96fd1..af98f62fad 100644 --- a/libavcodec/8bps.c +++ b/libavcodec/8bps.c @@ -47,8 +47,6 @@ typedef struct EightBpsContext { unsigned char planes; unsigned char planemap[4]; - -uint32_t pal[256]; } EightBpsContext; static int decode_frame(AVCodecContext *avctx, AVFrame *frame, @@ -123,9 +121,14 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, } if (avctx->bits_per_coded_sample <= 8) { -frame->palette_has_changed = ff_copy_palette(c->pal, avpkt, avctx); - -memcpy (frame->data[1], c->pal, AVPALETTE_SIZE); +#if FF_API_PALETTE_HAS_CHANGED +FF_DISABLE_DEPRECATION_WARNINGS +frame->palette_has_changed = +#endif +ff_copy_palette(frame->data[1], avpkt, avctx); +#if FF_API_PALETTE_HAS_CHANGED +FF_ENABLE_DEPRECATION_WARNINGS +#endif } *got_frame = 1; diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c index c1e31266ec..49c3770c4c 100644 --- a/libavcodec/ansi.c +++ b/libavcodec/ansi.c @@ -262,7 +262,11 @@ static int execute_code(AVCodecContext * avctx, int c) AV_GET_BUFFER_FLAG_REF)) < 0) return ret; s->frame->pict_type = AV_PICTURE_TYPE_I; +#if FF_API_PALETTE_HAS_CHANGED +FF_DISABLE_DEPRECATION_WARNINGS s->frame->palette_has_changed = 1; +FF_ENABLE_DEPRECATION_WARNINGS +#endif set_palette((uint32_t *)s->frame->data[1]); erase_screen(avctx); } else if (c == 'l') { @@ -371,7 +375,11 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe, } s->frame->pict_type = AV_PICTURE_TYPE_I; +#if FF_API_PALETTE_HAS_CHANGED +FF_DISABLE_DEPRECATION_WARNINGS s->frame->palette_has_changed = 1; +FF_ENABLE_DEPRECATION_WARNINGS +#endif set_palette((uint32_t *)s->frame->data[1]); if (!s->first_frame) { erase_screen(avctx); diff --git a/libavcodec/bethsoftvideo.c b/libavcodec/bethsoftvideo.c index e095d04fa5..6de502822b 100644 --- a/libavcodec/bethsoftvideo.c +++ b/libavcodec/bethsoftvideo.c @@ -63,7 +63,11 @@ static int set_palette(BethsoftvidContext *ctx, GetByteContext *g) palette[a] = 0xFFU << 24 | bytestream2_get_be24u(g) * 4
Re: [FFmpeg-devel] [PATCH 6/6] fate/cbs: add tests for discard_units
On Thu, 2023-05-18 at 05:23 +0800, Zhao Zhili wrote: > From: Zhao Zhili > > --- > tests/fate/cbs.mak | 28 ++ > tests/ref/fate/cbs-h264-discard-bidir| 37 + > tests/ref/fate/cbs-h264-discard-nonintra | 8 +++ > tests/ref/fate/cbs-h264-discard-nonkey | 3 ++ > tests/ref/fate/cbs-h264-discard-nonref | 67 > > tests/ref/fate/cbs-hevc-discard-bidir| 3 ++ > tests/ref/fate/cbs-hevc-discard-nonintra | 3 ++ > tests/ref/fate/cbs-hevc-discard-nonkey | 3 ++ > tests/ref/fate/cbs-hevc-discard-nonref | 26 + > 9 files changed, 178 insertions(+) > create mode 100644 tests/ref/fate/cbs-h264-discard-bidir > create mode 100644 tests/ref/fate/cbs-h264-discard-nonintra > create mode 100644 tests/ref/fate/cbs-h264-discard-nonkey > create mode 100644 tests/ref/fate/cbs-h264-discard-nonref > create mode 100644 tests/ref/fate/cbs-hevc-discard-bidir > create mode 100644 tests/ref/fate/cbs-hevc-discard-nonintra > create mode 100644 tests/ref/fate/cbs-hevc-discard-nonkey > create mode 100644 tests/ref/fate/cbs-hevc-discard-nonref It looks like patchwork cannot handle the patch due to the fate reference files, I think. How to format the patch to workaround the limitation? https://patchwork.ffmpeg.org/project/ffmpeg/patch/tencent_e5ae2e3995c2fdb4b8685e01f96b0a7d1...@qq.com/ The patch has been added as attachment of this email. From fc8ce5c7863560103749c9bc16a8e001f90231b8 Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Thu, 18 May 2023 01:49:24 +0800 Subject: [PATCH 6/6] fate/cbs: add tests for discard_units --- tests/fate/cbs.mak | 28 ++ tests/ref/fate/cbs-h264-discard-bidir| 37 + tests/ref/fate/cbs-h264-discard-nonintra | 8 +++ tests/ref/fate/cbs-h264-discard-nonkey | 3 ++ tests/ref/fate/cbs-h264-discard-nonref | 67 tests/ref/fate/cbs-hevc-discard-bidir| 3 ++ tests/ref/fate/cbs-hevc-discard-nonintra | 3 ++ tests/ref/fate/cbs-hevc-discard-nonkey | 3 ++ tests/ref/fate/cbs-hevc-discard-nonref | 26 + 9 files changed, 178 insertions(+) create mode 100644 tests/ref/fate/cbs-h264-discard-bidir create mode 100644 tests/ref/fate/cbs-h264-discard-nonintra create mode 100644 tests/ref/fate/cbs-h264-discard-nonkey create mode 100644 tests/ref/fate/cbs-h264-discard-nonref create mode 100644 tests/ref/fate/cbs-hevc-discard-bidir create mode 100644 tests/ref/fate/cbs-hevc-discard-nonintra create mode 100644 tests/ref/fate/cbs-hevc-discard-nonkey create mode 100644 tests/ref/fate/cbs-hevc-discard-nonref diff --git a/tests/fate/cbs.mak b/tests/fate/cbs.mak index a93e58ea9f..3d1ccf3897 100644 --- a/tests/fate/cbs.mak +++ b/tests/fate/cbs.mak @@ -12,6 +12,19 @@ FATE_CBS_$(1) += fate-cbs-$(1)-$(2) fate-cbs-$(1)-$(2): CMD = md5 -c:v $(3) -i $(TARGET_SAMPLES)/$(4) -c:v copy -y -bsf:v $(1)_metadata -f $(5) endef +define FATE_CBS_DISCARD_TEST +# (codec, discard_type, sample_file, output_format, dep) +FATE_CBS_$(1)_DISCARD += fate-cbs-$(1)-discard-$(2) + +tests/data/fate/cbs-$(1)-discard-$2.$(4): TAG = GEN +tests/data/fate/cbs-$(1)-discard-$2.$(4): ffmpeg$(PROGSSUF)$(EXESUF) $(5) | tests/data + $(M)$(TARGET_EXEC) $(TARGET_PATH)/ffmpeg$(PROGSSUF)$(EXESUF) -nostdin \ + -i $(3) -c:v copy -an -bsf:v filter_units=discard=$(2) \ + -f $(4) $(TARGET_PATH)/tests/data/fate/cbs-$(1)-discard-$(2).$(4) -y 2>/dev/null +fate-cbs-$(1)-discard-$2: ffprobe tests/data/fate/cbs-$(1)-discard-$(2).$(4) +fate-cbs-$(1)-discard-$2: CMD = ffprobe_demux $(TARGET_PATH)/tests/data/fate/cbs-$(1)-discard-$(2).$(4) +endef + # AV1 read/write FATE_CBS_AV1_CONFORMANCE_SAMPLES = \ @@ -67,6 +80,13 @@ $(foreach N,$(FATE_CBS_H264_SAMPLES),$(eval $(call FATE_CBS_TEST,h264,$(basename FATE_CBS_H264-$(call FATE_CBS_DEPS, H264, H264, H264, H264, H264) = $(FATE_CBS_h264) +$(eval $(call FATE_CBS_DISCARD_TEST,h264,nonref,$(TARGET_SAMPLES)/h264/interlaced_crop.mp4,mp4)) +$(eval $(call FATE_CBS_DISCARD_TEST,h264,bidir,$(TARGET_SAMPLES)/h264/interlaced_crop.mp4,mp4)) +$(eval $(call FATE_CBS_DISCARD_TEST,h264,nonintra,$(TARGET_SAMPLES)/h264/interlaced_crop.mp4,mp4)) +$(eval $(call FATE_CBS_DISCARD_TEST,h264,nonkey,$(TARGET_SAMPLES)/h264/interlaced_crop.mp4,mp4)) + +FATE_CBS_H264-$(call ALLYES, MP4_MUXER, H264_PARSER, FILTER_UNITS_BSF, H264_MUXER) += $(FATE_CBS_h264_DISCARD) + FATE_H264_REDUNDANT_PPS-$(call REMUX, H264, MOV_DEMUXER H264_REDUNDANT_PPS_BSF \ H264_DECODER H264_PARSER RAWVIDEO_ENCODER) \ @@ -133,6 +153,14 @@ FATE_CBS_HEVC_SAMPLES = \ $(foreach N,$(FATE_CBS_HEVC_SAMPLES),$(eval $(call FATE_CBS_TEST,hevc,$(basename $(N)),hevc,hevc-conformance/$(N),hevc))) FATE_CBS_HEVC-$(call FATE_CBS_DEPS, HEVC, HEVC, HEVC, HEVC, HEVC) = $(FATE_CBS_hevc) + +$(eval $(call FATE_CBS_DISCARD_TEST,hevc,nonref,$(TARGET_PATH)/tests/data/hevc-mp4.mov,mp4,tests/data/hevc-mp4.mov)) +$(eval $(call FATE_CBS_DISCARD_TEST,hevc,bidir,
Re: [FFmpeg-devel] [PATCH] avutil/frame: deprecate palette_has_changed
Quoting James Almer (2023-05-18 03:45:09) > Not only this is information that relies on the concept of a sequence of > frames, which is completely out of place as a field in AVFrame, but its > usefulness is also very limited. I think the wording can be stronger: there are NO known or intended uses of this field. Otherwise patch looks very good. -- 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".
[FFmpeg-devel] [PATCH] fftools/ffmpeg: rework handling -max_error_rate
Replace the decode_error_stat global with a per-input-stream variable. Also, print an error message when the error rate is exceeded. --- Now also printing the error rate value. --- fftools/ffmpeg.c | 33 + fftools/ffmpeg.h | 1 + fftools/ffmpeg_demux.c | 5 +++-- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 537f287637..414bae1747 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -121,7 +121,6 @@ static int64_t getmaxrss(void); int64_t nb_frames_dup = 0; int64_t nb_frames_drop = 0; -static int64_t decode_error_stat[2]; unsigned nb_output_dumped = 0; static BenchmarkTimeStamps current_time; @@ -771,8 +770,8 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti static void check_decode_result(InputStream *ist, int *got_output, int ret) { -if (*got_output || ret<0) -decode_error_stat[ret<0] ++; +if (ret < 0) +ist->decode_errors++; if (ret < 0 && exit_on_error) exit_program(1); @@ -1807,14 +1806,15 @@ static int transcode_step(OutputStream *ost) /* * The following code is the main loop of the file converter */ -static int transcode(void) +static int transcode(int *err_rate_exceeded) { -int ret, i; +int ret = 0, i; InputStream *ist; int64_t timer_start; print_stream_maps(); +*err_rate_exceeded = 0; atomic_store(&transcode_init_done, 1); if (stdin_interaction) { @@ -1855,9 +1855,20 @@ static int transcode(void) /* at the end of stream, we must flush the decoder buffers */ for (ist = ist_iter(NULL); ist; ist = ist_iter(ist)) { +float err_rate; + if (!input_files[ist->file_index]->eof_reached) { process_input_packet(ist, NULL, 0); } + +err_rate = (ist->frames_decoded || ist->decode_errors) ? + ist->decode_errors / (ist->frames_decoded + ist->decode_errors) : 0.f; +if (err_rate > max_error_rate) { +av_log(ist, AV_LOG_FATAL, "Decode error rate %g exceeds maximum %g\n", + err_rate, max_error_rate); +*err_rate_exceeded = 1; +} else if (err_rate) +av_log(ist, AV_LOG_VERBOSE, "Decode error rate %g\n", err_rate); } enc_flush(); @@ -1921,7 +1932,7 @@ static int64_t getmaxrss(void) int main(int argc, char **argv) { -int ret; +int ret, err_rate_exceeded; BenchmarkTimeStamps ti; init_dynload(); @@ -1958,7 +1969,7 @@ int main(int argc, char **argv) } current_time = ti = get_benchmark_time_stamps(); -ret = transcode(); +ret = transcode(&err_rate_exceeded); if (ret >= 0 && do_benchmark) { int64_t utime, stime, rtime; current_time = get_benchmark_time_stamps(); @@ -1969,12 +1980,10 @@ int main(int argc, char **argv) "bench: utime=%0.3fs stime=%0.3fs rtime=%0.3fs\n", utime / 100.0, stime / 100.0, rtime / 100.0); } -av_log(NULL, AV_LOG_DEBUG, "%"PRIu64" frames successfully decoded, %"PRIu64" decoding errors\n", - decode_error_stat[0], decode_error_stat[1]); -if ((decode_error_stat[0] + decode_error_stat[1]) * max_error_rate < decode_error_stat[1]) -exit_program(69); -ret = received_nb_signals ? 255 : ret; +ret = received_nb_signals ? 255 : + err_rate_exceeded ? 69 : ret; + exit_program(ret); return ret; } diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 3a332768df..87e684a147 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -413,6 +413,7 @@ typedef struct InputStream { // number of frames/samples retrieved from the decoder uint64_t frames_decoded; uint64_t samples_decoded; +uint64_t decode_errors; } InputStream; typedef struct LastFrameDuration { diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index df87e0f30a..401ae1f850 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -786,8 +786,9 @@ static void demux_final_stats(Demuxer *d) ds->nb_packets, ds->data_size); if (ist->decoding_needed) { -av_log(f, AV_LOG_VERBOSE, "%"PRIu64" frames decoded", - ist->frames_decoded); +av_log(f, AV_LOG_VERBOSE, + "%"PRIu64" frames decoded; %"PRIu64" decode errors", + ist->frames_decoded, ist->decode_errors); if (type == AVMEDIA_TYPE_AUDIO) av_log(f, AV_LOG_VERBOSE, " (%"PRIu64" samples)", ist->samples_decoded); av_log(f, AV_LOG_VERBOSE, "; "); -- 2.39.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] fftools/ffmpeg_dec: restructure audio/video decoding loop
It currently emulates the long-removed avcodec_decode_audio4/avcodec_decode_video2 APIs, which obfuscates the actual decoding flow. Restructure the decoding calls so that they naturally follow the new avcodec_send_packet()/avcodec_receive_frame() design. This is not only significantly easier to read, but also shorter. --- Now increments error rate for errors from avcodec_send_packet() --- fftools/ffmpeg_dec.c | 191 +++ 1 file changed, 65 insertions(+), 126 deletions(-) diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c index 646b587f9e..ab8c6205c6 100644 --- a/fftools/ffmpeg_dec.c +++ b/fftools/ffmpeg_dec.c @@ -31,7 +31,7 @@ #include "ffmpeg.h" -static void check_decode_result(InputStream *ist, int *got_output, int ret) +static void check_decode_result(InputStream *ist, int got_output, int ret) { if (ret < 0) ist->decode_errors++; @@ -39,7 +39,7 @@ static void check_decode_result(InputStream *ist, int *got_output, int ret) if (ret < 0 && exit_on_error) exit_program(1); -if (*got_output && ist->dec_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE) { +if (got_output && ist->dec_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE) { if (ist->decoded_frame->decode_error_flags || (ist->decoded_frame->flags & AV_FRAME_FLAG_CORRUPT)) { av_log(ist, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING, "corrupt decoded frame\n"); @@ -49,52 +49,6 @@ static void check_decode_result(InputStream *ist, int *got_output, int ret) } } -// This does not quite work like avcodec_decode_audio4/avcodec_decode_video2. -// There is the following difference: if you got a frame, you must call -// it again with pkt=NULL. pkt==NULL is treated differently from pkt->size==0 -// (pkt==NULL means get more output, pkt->size==0 is a flush/drain packet) -static int decode(InputStream *ist, AVCodecContext *avctx, - AVFrame *frame, int *got_frame, const AVPacket *pkt) -{ -int ret; - -*got_frame = 0; - -if (pkt) { -ret = avcodec_send_packet(avctx, pkt); -// In particular, we don't expect AVERROR(EAGAIN), because we read all -// decoded frames with avcodec_receive_frame() until done. -if (ret < 0 && ret != AVERROR_EOF) -return ret; -} - -ret = avcodec_receive_frame(avctx, frame); -if (ret < 0 && ret != AVERROR(EAGAIN)) -return ret; -if (ret >= 0) { -if (ist->want_frame_data) { -FrameData *fd; - -av_assert0(!frame->opaque_ref); -frame->opaque_ref = av_buffer_allocz(sizeof(*fd)); -if (!frame->opaque_ref) { -av_frame_unref(frame); -return AVERROR(ENOMEM); -} -fd = (FrameData*)frame->opaque_ref->data; -fd->pts = frame->pts; -fd->tb = avctx->pkt_timebase; -fd->idx = avctx->frame_num - 1; -} - -frame->time_base = avctx->pkt_timebase; - -*got_frame = 1; -} - -return 0; -} - static int send_frame_to_filters(InputStream *ist, AVFrame *decoded_frame) { int i, ret; @@ -192,25 +146,10 @@ static void audio_ts_process(InputStream *ist, AVFrame *frame) frame->time_base = tb_filter; } -static int decode_audio(InputStream *ist, const AVPacket *pkt, int *got_output, -int *decode_failed) +static int decode_audio(InputStream *ist, AVFrame *decoded_frame) { -AVFrame *decoded_frame = ist->decoded_frame; -AVCodecContext *avctx = ist->dec_ctx; int ret, err = 0; -update_benchmark(NULL); -ret = decode(ist, avctx, decoded_frame, got_output, pkt); -update_benchmark("decode_audio %d.%d", ist->file_index, ist->st->index); -if (ret < 0) -*decode_failed = 1; - -if (ret != AVERROR_EOF) -check_decode_result(ist, got_output, ret); - -if (!*got_output || ret < 0) -return ret; - ist->samples_decoded += decoded_frame->nb_samples; ist->frames_decoded++; @@ -274,24 +213,10 @@ static int64_t video_duration_estimate(const InputStream *ist, const AVFrame *fr return FFMAX(ist->last_frame_duration_est, 1); } -static int decode_video(InputStream *ist, const AVPacket *pkt, int *got_output, -int eof, int *decode_failed) +static int decode_video(InputStream *ist, AVFrame *frame) { -AVFrame *frame = ist->decoded_frame; int ret = 0, err = 0; -// With fate-indeo3-2, we're getting 0-sized packets before EOF for some -// reason. This seems like a semi-critical bug. Don't trigger EOF, and -// skip the packet. -if (!eof && pkt && pkt->size == 0) -return 0; - -update_benchmark(NULL); -ret = decode(ist, ist->dec_ctx, frame, got_output, pkt); -update_benchmark("decode_video %d.%d", ist->file_index, ist->st->index); -if (ret < 0) -*decode_failed = 1; - // The following line may be required in some
Re: [FFmpeg-devel] [PATCH 31/36] fftools/ffmpeg_dec: restructure audio/video decoding loop
Quoting Michael Niedermayer (2023-05-17 22:04:09) > On Wed, May 17, 2023 at 12:20:24PM +0200, Anton Khirnov wrote: > > It currently emulates the long-removed > > avcodec_decode_audio4/avcodec_decode_video2 APIs, which obfuscates the > > actual decoding flow. Restructure the decoding calls so that they > > naturally follow the new avcodec_send_packet()/avcodec_receive_frame() > > design. > > > > This is not only significantly easier to read, but also shorter. > > with this: > ./ffmpeg -y -threads:a 1 -i tickets/1208/702121h264-TTA.mkvtest82.mkv > -bitexact -vn file1208.mp3 > > Both before and afterwards the output is empty and we see > > Finishing stream without any data written to it. > Output file is empty, nothing was encoded > > after this patch while the output is not any better, now ffmpeg proclaims > success with its return code > > just to be sure i try reading the output > > [mp3 @ 0x5635bab17900] Format mp3 detected only with low score of 1, > misdetection possible! > [mp3 @ 0x5635bab17900] Failed to read frame size: Could not seek to 1026. > [in#0 @ 0x5635bab177c0] Error opening input: Invalid argument > > I dont think that convertion was successfull Your original failure has nothing to do with the output file being empty, as that is not considered an error unless you specify -abort_on empty_output Rather the failure comes from the default maximum error rate of 2/3 being exceeded, since no frame could be decoded successfully. The reason was that the patch did not count avcodec_send_packet() errors into error rate, I've fixed that in a new version. I've also updated the -max_error_rate patch to make the situation clearer. -- 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".
[FFmpeg-devel] [PATCH 1/3] lavc/qsvenc: use the right alignment instead of hard coded value
From: Haihao Xiang Signed-off-by: Haihao Xiang --- libavcodec/qsvenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 0ed1f757d4..2c38fbf0dc 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -1909,7 +1909,7 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame, } else { /* make a copy if the input is not padded as libmfx requires */ /* and to make allocation continious for data[0]/data[1] */ - if ((frame->height & 31 || frame->linesize[0] & (q->width_align - 1)) || + if ((frame->height & (q->height_align - 1) || frame->linesize[0] & (q->width_align - 1)) || (frame->data[1] - frame->data[0] != frame->linesize[0] * FFALIGN(qf->frame->height, q->height_align))) { int tmp_w, tmp_h; qf->frame->height = tmp_h = FFALIGN(frame->height, q->height_align); -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/3] lavc/qsvenc: make sure continuous allocation
From: Haihao Xiang Intel MediaSDK and oneVPL expect continuous allocation for data[i], however there are mandatory padding bytes between data[i] and data[i+1]. when calling av_frame_get_buffer. This patch removes all extra padding bytes. Signed-off-by: Haihao Xiang --- libavcodec/qsvenc.c | 58 - 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index b6813b3023..4ae9a92490 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -1882,6 +1882,62 @@ static int qsvenc_fill_padding_area(AVFrame *frame, int new_w, int new_h) return 0; } +/* frame width / height have been aligned with the alignment */ +static int qsvenc_get_continuous_buffer(AVFrame *frame) +{ +int total_size; + +switch (frame->format) { +case AV_PIX_FMT_NV12: +frame->linesize[0] = frame->width; +frame->linesize[1] = frame->linesize[0]; +total_size = frame->linesize[0] * frame->height + frame->linesize[1] * frame->height / 2; +break; + +case AV_PIX_FMT_P010: +case AV_PIX_FMT_P012: +frame->linesize[0] = 2 * frame->width; +frame->linesize[1] = frame->linesize[0]; +total_size = frame->linesize[0] * frame->height + frame->linesize[1] * frame->height / 2; +break; + +case AV_PIX_FMT_YUYV422: +frame->linesize[0] = 2 * frame->width; +frame->linesize[1] = 0; +total_size = frame->linesize[0] * frame->height; +break; + +case AV_PIX_FMT_Y210: +case AV_PIX_FMT_VUYX: +case AV_PIX_FMT_XV30: +case AV_PIX_FMT_BGRA: +case AV_PIX_FMT_X2RGB10: +frame->linesize[0] = 4 * frame->width; +frame->linesize[1] = 0; +total_size = frame->linesize[0] * frame->height; +break; + +default: +// This should never be reached +av_assert0(0); +return AVERROR(EINVAL); +} + +frame->buf[0] = av_buffer_alloc(total_size); +if (!frame->buf[0]) +return AVERROR(ENOMEM); + +frame->data[0] = frame->buf[0]->data; +frame->extended_data = frame->data; + +if (frame->format == AV_PIX_FMT_NV12 || +frame->format == AV_PIX_FMT_P010 || +frame->format == AV_PIX_FMT_P012) +frame->data[1] = frame->data[0] + frame->linesize[0] * frame->height; + +return 0; +} + static int submit_frame(QSVEncContext *q, const AVFrame *frame, QSVFrame **new_frame) { @@ -1919,7 +1975,7 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame, qf->frame->format = frame->format; if (!qf->frame->data[0]) { -ret = av_frame_get_buffer(qf->frame, q->width_align); +ret = qsvenc_get_continuous_buffer(qf->frame); if (ret < 0) return ret; } -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/3] lavc/qsvenc: avoid data copy if possible
From: Haihao Xiang The data copy is unnecessary for packed formats when frame width and height are aligned For example: $ ffmpeg -f lavfi -i testsrc=size=1920x1088 -vf "format=yuyv422" -c:v hevc_qsv -f null - Signed-off-by: Haihao Xiang --- libavcodec/qsvenc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 2c38fbf0dc..b6813b3023 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -1910,7 +1910,8 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame, /* make a copy if the input is not padded as libmfx requires */ /* and to make allocation continious for data[0]/data[1] */ if ((frame->height & (q->height_align - 1) || frame->linesize[0] & (q->width_align - 1)) || -(frame->data[1] - frame->data[0] != frame->linesize[0] * FFALIGN(qf->frame->height, q->height_align))) { +((frame->format == AV_PIX_FMT_NV12 || frame->format == AV_PIX_FMT_P010 || frame->format == AV_PIX_FMT_P012) && + (frame->data[1] - frame->data[0] != frame->linesize[0] * FFALIGN(qf->frame->height, q->height_align { int tmp_w, tmp_h; qf->frame->height = tmp_h = FFALIGN(frame->height, q->height_align); qf->frame->width = tmp_w = FFALIGN(frame->width, q->width_align); -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".