[FFmpeg-devel] [PATCH] configure: link to libatomic when it's present

2022-01-19 Thread Anton Khirnov
C11 atomics in some configurations (e.g. 64bit operations on ppc64 with
GCC) require linking to libatomic.
---
Testing welcome, especially in configurations where
* libatomic is not present
* libatomic is actually needed
---
 configure | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 1413122d87..1ff5dbee5b 100755
--- a/configure
+++ b/configure
@@ -6324,7 +6324,14 @@ check_headers asm/types.h
 # it seems there are versions of clang in some distros that try to use the
 # gcc headers, which explodes for stdatomic
 # so we also check that atomics actually work here
-check_builtin stdatomic stdatomic.h "atomic_int foo, bar = 
ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += bar"
+#
+# some configurations also require linking to libatomic, so try
+# both with -latomic and without
+for LATOMIC in "-latomic" ""; do
+check_builtin stdatomic stdatomic.h
 \
+"atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo 
+= bar"  \
+$LATOMIC && add_extralibs $LATOMIC && break
+done
 
 check_lib advapi32 "windows.h"RegCloseKey  -ladvapi32
 check_lib bcrypt   "windows.h bcrypt.h"   BCryptGenRandom  -lbcrypt &&
-- 
2.33.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] configure: link to libatomic when it's present

2022-01-19 Thread James Almer




On 1/19/2022 8:54 AM, Anton Khirnov wrote:

C11 atomics in some configurations (e.g. 64bit operations on ppc64 with
GCC) require linking to libatomic.
---
Testing welcome, especially in configurations where
* libatomic is not present
* libatomic is actually needed
---
  configure | 9 -
  1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 1413122d87..1ff5dbee5b 100755
--- a/configure
+++ b/configure
@@ -6324,7 +6324,14 @@ check_headers asm/types.h
  # it seems there are versions of clang in some distros that try to use the
  # gcc headers, which explodes for stdatomic
  # so we also check that atomics actually work here
-check_builtin stdatomic stdatomic.h "atomic_int foo, bar = ATOMIC_VAR_INIT(-1); 
atomic_store(&foo, 0); foo += bar"
+#
+# some configurations also require linking to libatomic, so try
+# both with -latomic and without
+for LATOMIC in "-latomic" ""; do


Shouldn't you try without it first? On my toolchain libatomic is 
present, but libraries compile without linking to it just fine. That 
changes after this patch, where it starts linking to it explicitly.



+check_builtin stdatomic stdatomic.h
 \
+"atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += 
bar"  \
+$LATOMIC && add_extralibs $LATOMIC && break


You should probably add it to the required libraries' extralibs only.
Just replace the add_extralibs part with setting stdatomic_extralibs to 
$LATOMIC, and then add stdatomic to all the libraries' _suggest lists, 
same as we do for libm.



+done
  
  check_lib advapi32 "windows.h"RegCloseKey  -ladvapi32

  check_lib bcrypt   "windows.h bcrypt.h"   BCryptGenRandom  -lbcrypt &&

___
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] configure: link to libatomic when it's present

2022-01-19 Thread Andreas Rheinhardt
James Almer:
> 
> 
> On 1/19/2022 8:54 AM, Anton Khirnov wrote:
>> C11 atomics in some configurations (e.g. 64bit operations on ppc64 with
>> GCC) require linking to libatomic.
>> ---
>> Testing welcome, especially in configurations where
>> * libatomic is not present
>> * libatomic is actually needed
>> ---
>>   configure | 9 -
>>   1 file changed, 8 insertions(+), 1 deletion(-)
>>
>> diff --git a/configure b/configure
>> index 1413122d87..1ff5dbee5b 100755
>> --- a/configure
>> +++ b/configure
>> @@ -6324,7 +6324,14 @@ check_headers asm/types.h
>>   # it seems there are versions of clang in some distros that try to
>> use the
>>   # gcc headers, which explodes for stdatomic
>>   # so we also check that atomics actually work here
>> -check_builtin stdatomic stdatomic.h "atomic_int foo, bar =
>> ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += bar"
>> +#
>> +# some configurations also require linking to libatomic, so try
>> +# both with -latomic and without
>> +for LATOMIC in "-latomic" ""; do
> 
> Shouldn't you try without it first? On my toolchain libatomic is
> present, but libraries compile without linking to it just fine. That
> changes after this patch, where it starts linking to it explicitly.
> 

This would work if this test checked for all the atomic operations that
might be needed; but it doesn't: It checks just for atomic increment and
only for atomic_int. What is if atomic_increment can be done without
recourse to libatomic because of hardware support whereas another atomic
operation needs libatomic?

>> +    check_builtin stdatomic
>> stdatomic.h \
>> +    "atomic_int foo, bar = ATOMIC_VAR_INIT(-1);
>> atomic_store(&foo, 0); foo += bar"  \
>> +    $LATOMIC && add_extralibs $LATOMIC && break
> 
> You should probably add it to the required libraries' extralibs only.
> Just replace the add_extralibs part with setting stdatomic_extralibs to
> $LATOMIC, and then add stdatomic to all the libraries' _suggest lists,
> same as we do for libm.
> 
>> +done
>>     check_lib advapi32 "windows.h"    RegCloseKey 
>> -ladvapi32
>>   check_lib bcrypt   "windows.h bcrypt.h"   BCryptGenRandom 
>> -lbcrypt &&
___
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] configure: link to libatomic when it's present

2022-01-19 Thread Anton Khirnov
Quoting James Almer (2022-01-19 13:34:20)
> 
> 
> On 1/19/2022 8:54 AM, Anton Khirnov wrote:
> > C11 atomics in some configurations (e.g. 64bit operations on ppc64 with
> > GCC) require linking to libatomic.
> > ---
> > Testing welcome, especially in configurations where
> > * libatomic is not present
> > * libatomic is actually needed
> > ---
> >   configure | 9 -
> >   1 file changed, 8 insertions(+), 1 deletion(-)
> > 
> > diff --git a/configure b/configure
> > index 1413122d87..1ff5dbee5b 100755
> > --- a/configure
> > +++ b/configure
> > @@ -6324,7 +6324,14 @@ check_headers asm/types.h
> >   # it seems there are versions of clang in some distros that try to use the
> >   # gcc headers, which explodes for stdatomic
> >   # so we also check that atomics actually work here
> > -check_builtin stdatomic stdatomic.h "atomic_int foo, bar = 
> > ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += bar"
> > +#
> > +# some configurations also require linking to libatomic, so try
> > +# both with -latomic and without
> > +for LATOMIC in "-latomic" ""; do
> 
> Shouldn't you try without it first? On my toolchain libatomic is 
> present, but libraries compile without linking to it just fine. That 
> changes after this patch, where it starts linking to it explicitly.

No, because it may only be needed for some atomic sizes and operations,
which the test in configure doesn't necessarily catch.
And because we pass as-needed to the linker, the built libraries
shouldn't actually require libatomic unless it's really needed.

> 
> > +check_builtin stdatomic stdatomic.h
> >  \
> > +"atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); 
> > foo += bar"  \
> > +$LATOMIC && add_extralibs $LATOMIC && break
> 
> You should probably add it to the required libraries' extralibs only.
> Just replace the add_extralibs part with setting stdatomic_extralibs to 
> $LATOMIC, and then add stdatomic to all the libraries' _suggest lists, 
> same as we do for libm.

Then we need to actively track which libraries actually use atomics,
which also depends on which features are enabled. Given that this only
fails on less-common arches, this sounds like a recipe for obscure build
failures. Given that it's only really linked when needed, it seems
better to just add it unconditionally.

-- 
Anton Khirnov
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] configure: link to libatomic when it's present

2022-01-19 Thread James Almer

On 1/19/2022 9:40 AM, Anton Khirnov wrote:

Quoting James Almer (2022-01-19 13:34:20)



On 1/19/2022 8:54 AM, Anton Khirnov wrote:

C11 atomics in some configurations (e.g. 64bit operations on ppc64 with
GCC) require linking to libatomic.
---
Testing welcome, especially in configurations where
* libatomic is not present
* libatomic is actually needed
---
   configure | 9 -
   1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 1413122d87..1ff5dbee5b 100755
--- a/configure
+++ b/configure
@@ -6324,7 +6324,14 @@ check_headers asm/types.h
   # it seems there are versions of clang in some distros that try to use the
   # gcc headers, which explodes for stdatomic
   # so we also check that atomics actually work here
-check_builtin stdatomic stdatomic.h "atomic_int foo, bar = ATOMIC_VAR_INIT(-1); 
atomic_store(&foo, 0); foo += bar"
+#
+# some configurations also require linking to libatomic, so try
+# both with -latomic and without
+for LATOMIC in "-latomic" ""; do


Shouldn't you try without it first? On my toolchain libatomic is
present, but libraries compile without linking to it just fine. That
changes after this patch, where it starts linking to it explicitly.


No, because it may only be needed for some atomic sizes and operations,
which the test in configure doesn't necessarily catch.
And because we pass as-needed to the linker, the built libraries
shouldn't actually require libatomic unless it's really needed.


Ah, didn't consider --as-needed.






+check_builtin stdatomic stdatomic.h
 \
+"atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += 
bar"  \
+$LATOMIC && add_extralibs $LATOMIC && break


You should probably add it to the required libraries' extralibs only.
Just replace the add_extralibs part with setting stdatomic_extralibs to
$LATOMIC, and then add stdatomic to all the libraries' _suggest lists,
same as we do for libm.


Then we need to actively track which libraries actually use atomics,
which also depends on which features are enabled. Given that this only
fails on less-common arches, this sounds like a recipe for obscure build
failures. Given that it's only really linked when needed, it seems
better to just add it unconditionally.


Then just add it to all of them, like we do for libm.

What i want to avoid is having it in EXTRALIBS. There was a huge 
configure rework long ago that removed everything from that variable 
(leaving it as the place where user defined --extra-libs arguments are 
dumped), and fine tuned ld arguments in a per library/module basis. I'd 
like to not go back to start dumping everything in EXTRALIBS.


Like this, on top of this patch:


diff --git a/configure b/configure
index 1ff5dbee5b..43713a7679 100755
--- a/configure
+++ b/configure
@@ -3794,20 +3794,20 @@ cws2fws_extralibs="zlib_extralibs"

 # libraries, in any order
 avcodec_deps="avutil"
-avcodec_suggest="libm"
+avcodec_suggest="libm stdatomic"
 avdevice_deps="avformat avcodec avutil"
-avdevice_suggest="libm"
+avdevice_suggest="libm stdatomic"
 avfilter_deps="avutil"
-avfilter_suggest="libm"
+avfilter_suggest="libm stdatomic"
 avformat_deps="avcodec avutil"
-avformat_suggest="libm network zlib"
-avutil_suggest="clock_gettime ffnvcodec libm libdrm libmfx opencl user32 vaapi 
vulkan videotoolbox corefoundation corevideo coremedia bcrypt"
+avformat_suggest="libm network stdatomic zlib"
+avutil_suggest="clock_gettime ffnvcodec libm libdrm libmfx opencl stdatomic user32 
vaapi vulkan videotoolbox corefoundation corevideo coremedia bcrypt"
 postproc_deps="avutil gpl"
-postproc_suggest="libm"
+postproc_suggest="libm stdatomic"
 swresample_deps="avutil"
-swresample_suggest="libm libsoxr"
+swresample_suggest="libm libsoxr stdatomic"
 swscale_deps="avutil"
-swscale_suggest="libm"
+swscale_suggest="libm stdatomic"

 avcodec_extralibs="pthreads_extralibs iconv_extralibs dxva2_extralibs"
 avfilter_extralibs="pthreads_extralibs"
@@ -6330,7 +6330,7 @@ check_headers asm/types.h
 for LATOMIC in "-latomic" ""; do
 check_builtin stdatomic stdatomic.h
 \
 "atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += 
bar"  \
-$LATOMIC && add_extralibs $LATOMIC && break
+$LATOMIC && eval stdatomic_extralibs="\$LATOMIC" && break
 done

 check_lib advapi32 "windows.h"RegCloseKey  -ladvapi32

___
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] lavu/hwcontext_opencl: clear dangling pointers on map failure

2022-01-19 Thread Anton Khirnov
---
untested
---
 libavutil/hwcontext_opencl.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libavutil/hwcontext_opencl.c b/libavutil/hwcontext_opencl.c
index 26a3a24593..40ee611943 100644
--- a/libavutil/hwcontext_opencl.c
+++ b/libavutil/hwcontext_opencl.c
@@ -2146,6 +2146,7 @@ fail:
 clReleaseMemObject(mapping->frame.planes[p]);
 }
 av_free(mapping);
+memset(dst->data, 0, sizeof(dst->data));
 return err;
 }
 
@@ -2317,6 +2318,7 @@ fail:
 if (desc->planes[p])
 clReleaseMemObject(desc->planes[p]);
 av_freep(&desc);
+memset(dst->data, 0, sizeof(dst->data));
 return err;
 }
 
@@ -2407,6 +2409,7 @@ fail:
 0, NULL, &event);
 if (cle == CL_SUCCESS)
 opencl_wait_events(dst_fc, &event, 1);
+memset(dst->data, 0, sizeof(dst->data));
 return err;
 }
 
@@ -2562,6 +2565,7 @@ fail:
 0, NULL, &event);
 if (cle == CL_SUCCESS)
 opencl_wait_events(dst_fc, &event, 1);
+memset(dst->data, 0, sizeof(dst->data));
 return err;
 }
 
@@ -2793,6 +2797,7 @@ fail:
 clReleaseMemObject(mapping->object_buffers[i]);
 }
 av_free(mapping);
+memset(dst->data, 0, sizeof(dst->data));
 return err;
 }
 
-- 
2.33.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 2/3] lavu/hwcontext_vulkan: clear dangling pointers on map failure

2022-01-19 Thread Anton Khirnov
---
untested
---
 libavutil/hwcontext_vulkan.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 60a6cf6a91..ae19fc2ab6 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -2927,6 +2927,7 @@ static int vulkan_map_from_drm(AVHWFramesContext *hwfc, 
AVFrame *dst,
 
 fail:
 vulkan_frame_free(hwfc->device_ctx->hwctx, (uint8_t *)f);
+dst->data[0] = NULL;
 return err;
 }
 
-- 
2.33.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 3/3] lavu/hwcontext: clarify behavior on av_hwframe_map() failure

2022-01-19 Thread Anton Khirnov
Clear anything that av_hwframe_map() might have done to the destination
frame, but leave caller-provided fields unchanged.
---
 libavutil/hwcontext.c | 23 +--
 libavutil/hwcontext.h |  4 
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c
index 31c7840dba..ae33da1262 100644
--- a/libavutil/hwcontext.c
+++ b/libavutil/hwcontext.c
@@ -18,6 +18,7 @@
 
 #include "config.h"
 
+#include "avassert.h"
 #include "buffer.h"
 #include "common.h"
 #include "hwcontext.h"
@@ -788,6 +789,8 @@ fail:
 
 int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
 {
+AVBufferRef*orig_dst_frames = dst->hw_frames_ctx;
+enum AVPixelFormat orig_dst_fmt = dst->format;
 AVHWFramesContext *src_frames, *dst_frames;
 HWMapDescriptor *hwmap;
 int ret;
@@ -825,7 +828,7 @@ int av_hwframe_map(AVFrame *dst, const AVFrame *src, int 
flags)
 ret = src_frames->internal->hw_type->map_from(src_frames,
   dst, src, flags);
 if (ret != AVERROR(ENOSYS))
-return ret;
+goto fail;
 }
 }
 
@@ -837,11 +840,27 @@ int av_hwframe_map(AVFrame *dst, const AVFrame *src, int 
flags)
 ret = dst_frames->internal->hw_type->map_to(dst_frames,
 dst, src, flags);
 if (ret != AVERROR(ENOSYS))
-return ret;
+goto fail;
 }
 }
 
 return AVERROR(ENOSYS);
+
+fail:
+// if the caller provided dst frames context, it should be preserved
+// by this function
+av_assert0(orig_dst_frames == NULL ||
+   orig_dst_frames == dst->hw_frames_ctx);
+
+// preserve user-provided dst frame fields, but clean
+// anything we might have set
+dst->hw_frames_ctx = NULL;
+av_frame_unref(dst);
+
+dst->hw_frames_ctx = orig_dst_frames;
+dst->format= orig_dst_fmt;
+
+return ret;
 }
 
 int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx,
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index 04d19d89c2..c18b7e1e8b 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -571,6 +571,10 @@ enum {
  * possible with the given arguments and hwframe setup, while other return
  * values indicate that it failed somehow.
  *
+ * On failure, the destination frame will be left blank, except for the
+ * hw_frames_ctx/format fields thay may have been set by the caller - those 
will
+ * be preserved as they were.
+ *
  * @param dst Destination frame, to contain the mapping.
  * @param src Source frame, to be mapped.
  * @param flags Some combination of AV_HWFRAME_MAP_* flags.
-- 
2.33.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 3/3] lavu/hwcontext: clarify behavior on av_hwframe_map() failure

2022-01-19 Thread James Almer




On 1/19/2022 10:40 AM, Anton Khirnov wrote:

Clear anything that av_hwframe_map() might have done to the destination
frame, but leave caller-provided fields unchanged.
---
  libavutil/hwcontext.c | 23 +--
  libavutil/hwcontext.h |  4 
  2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c
index 31c7840dba..ae33da1262 100644
--- a/libavutil/hwcontext.c
+++ b/libavutil/hwcontext.c
@@ -18,6 +18,7 @@
  
  #include "config.h"
  
+#include "avassert.h"

  #include "buffer.h"
  #include "common.h"
  #include "hwcontext.h"
@@ -788,6 +789,8 @@ fail:
  
  int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)

  {
+AVBufferRef*orig_dst_frames = dst->hw_frames_ctx;
+enum AVPixelFormat orig_dst_fmt = dst->format;
  AVHWFramesContext *src_frames, *dst_frames;
  HWMapDescriptor *hwmap;
  int ret;
@@ -825,7 +828,7 @@ int av_hwframe_map(AVFrame *dst, const AVFrame *src, int 
flags)
  ret = src_frames->internal->hw_type->map_from(src_frames,
dst, src, flags);
  if (ret != AVERROR(ENOSYS))
-return ret;
+goto fail;


What if ret is 0? Is the stuff in the fail label meant to run on success?


  }
  }
  
@@ -837,11 +840,27 @@ int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)

  ret = dst_frames->internal->hw_type->map_to(dst_frames,
  dst, src, flags);
  if (ret != AVERROR(ENOSYS))
-return ret;
+goto fail;
  }
  }
  
  return AVERROR(ENOSYS);

+
+fail:
+// if the caller provided dst frames context, it should be preserved
+// by this function
+av_assert0(orig_dst_frames == NULL ||
+   orig_dst_frames == dst->hw_frames_ctx);
+
+// preserve user-provided dst frame fields, but clean
+// anything we might have set
+dst->hw_frames_ctx = NULL;
+av_frame_unref(dst);
+
+dst->hw_frames_ctx = orig_dst_frames;
+dst->format= orig_dst_fmt;
+
+return ret;
  }
  
  int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx,

diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index 04d19d89c2..c18b7e1e8b 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -571,6 +571,10 @@ enum {
   * possible with the given arguments and hwframe setup, while other return
   * values indicate that it failed somehow.
   *
+ * On failure, the destination frame will be left blank, except for the
+ * hw_frames_ctx/format fields thay may have been set by the caller - those 
will
+ * be preserved as they were.
+ *
   * @param dst Destination frame, to contain the mapping.
   * @param src Source frame, to be mapped.
   * @param flags Some combination of AV_HWFRAME_MAP_* flags.

___
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 3/3] lavu/hwcontext: clarify behavior on av_hwframe_map() failure

2022-01-19 Thread Anton Khirnov
Quoting James Almer (2022-01-19 14:45:12)
> 
> 
> On 1/19/2022 10:40 AM, Anton Khirnov wrote:
> > Clear anything that av_hwframe_map() might have done to the destination
> > frame, but leave caller-provided fields unchanged.
> > ---
> >   libavutil/hwcontext.c | 23 +--
> >   libavutil/hwcontext.h |  4 
> >   2 files changed, 25 insertions(+), 2 deletions(-)
> > 
> > diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c
> > index 31c7840dba..ae33da1262 100644
> > --- a/libavutil/hwcontext.c
> > +++ b/libavutil/hwcontext.c
> > @@ -18,6 +18,7 @@
> >   
> >   #include "config.h"
> >   
> > +#include "avassert.h"
> >   #include "buffer.h"
> >   #include "common.h"
> >   #include "hwcontext.h"
> > @@ -788,6 +789,8 @@ fail:
> >   
> >   int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
> >   {
> > +AVBufferRef*orig_dst_frames = dst->hw_frames_ctx;
> > +enum AVPixelFormat orig_dst_fmt = dst->format;
> >   AVHWFramesContext *src_frames, *dst_frames;
> >   HWMapDescriptor *hwmap;
> >   int ret;
> > @@ -825,7 +828,7 @@ int av_hwframe_map(AVFrame *dst, const AVFrame *src, 
> > int flags)
> >   ret = src_frames->internal->hw_type->map_from(src_frames,
> > dst, src, 
> > flags);
> >   if (ret != AVERROR(ENOSYS))
> > -return ret;
> > +goto fail;
> 
> What if ret is 0? Is the stuff in the fail label meant to run on success?

Critical brain failure. Will fix.

-- 
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] configure: link to libatomic when it's present

2022-01-19 Thread Anton Khirnov
C11 atomics in some configurations (e.g. 64bit operations on ppc64 with
GCC) require linking to libatomic.

Fixes #9275
---
 configure | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/configure b/configure
index 1413122d87..3059c154df 100755
--- a/configure
+++ b/configure
@@ -3794,20 +3794,20 @@ cws2fws_extralibs="zlib_extralibs"
 
 # libraries, in any order
 avcodec_deps="avutil"
-avcodec_suggest="libm"
+avcodec_suggest="libm stdatomic"
 avdevice_deps="avformat avcodec avutil"
-avdevice_suggest="libm"
+avdevice_suggest="libm stdatomic"
 avfilter_deps="avutil"
-avfilter_suggest="libm"
+avfilter_suggest="libm stdatomic"
 avformat_deps="avcodec avutil"
-avformat_suggest="libm network zlib"
-avutil_suggest="clock_gettime ffnvcodec libm libdrm libmfx opencl user32 vaapi 
vulkan videotoolbox corefoundation corevideo coremedia bcrypt"
+avformat_suggest="libm network zlib stdatomic"
+avutil_suggest="clock_gettime ffnvcodec libm libdrm libmfx opencl user32 vaapi 
vulkan videotoolbox corefoundation corevideo coremedia bcrypt stdatomic"
 postproc_deps="avutil gpl"
-postproc_suggest="libm"
+postproc_suggest="libm stdatomic"
 swresample_deps="avutil"
-swresample_suggest="libm libsoxr"
+swresample_suggest="libm libsoxr stdatomic"
 swscale_deps="avutil"
-swscale_suggest="libm"
+swscale_suggest="libm stdatomic"
 
 avcodec_extralibs="pthreads_extralibs iconv_extralibs dxva2_extralibs"
 avfilter_extralibs="pthreads_extralibs"
@@ -6324,7 +6324,14 @@ check_headers asm/types.h
 # it seems there are versions of clang in some distros that try to use the
 # gcc headers, which explodes for stdatomic
 # so we also check that atomics actually work here
-check_builtin stdatomic stdatomic.h "atomic_int foo, bar = 
ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += bar"
+#
+# some configurations also require linking to libatomic, so try
+# both with -latomic and without
+for LATOMIC in "-latomic" ""; do
+check_builtin stdatomic stdatomic.h
 \
+"atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo 
+= bar"  \
+$LATOMIC && eval stdatomic_extralibs="\$LATOMIC" && break
+done
 
 check_lib advapi32 "windows.h"RegCloseKey  -ladvapi32
 check_lib bcrypt   "windows.h bcrypt.h"   BCryptGenRandom  -lbcrypt &&
-- 
2.33.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] lavu/hwcontext: clarify behavior on av_hwframe_map() failure

2022-01-19 Thread Anton Khirnov
Clear anything that av_hwframe_map() might have done to the destination
frame, but leave caller-provided fields unchanged.
---
Interdiff:
  diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c
  index ae33da1262..ab9ad3703e 100644
  --- a/libavutil/hwcontext.c
  +++ b/libavutil/hwcontext.c
  @@ -827,7 +827,9 @@ int av_hwframe_map(AVFrame *dst, const AVFrame *src, int 
flags)
   src_frames->internal->hw_type->map_from) {
   ret = src_frames->internal->hw_type->map_from(src_frames,
 dst, src, flags);
  -if (ret != AVERROR(ENOSYS))
  +if (ret >= 0)
  +return ret;
  +else if (ret != AVERROR(ENOSYS))
   goto fail;
   }
   }
  @@ -839,7 +841,9 @@ int av_hwframe_map(AVFrame *dst, const AVFrame *src, int 
flags)
   dst_frames->internal->hw_type->map_to) {
   ret = dst_frames->internal->hw_type->map_to(dst_frames,
   dst, src, flags);
  -if (ret != AVERROR(ENOSYS))
  +if (ret >= 0)
  +return ret;
  +else if (ret != AVERROR(ENOSYS))
   goto fail;
   }
   }

 libavutil/hwcontext.c | 27 +--
 libavutil/hwcontext.h |  4 
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c
index 31c7840dba..ab9ad3703e 100644
--- a/libavutil/hwcontext.c
+++ b/libavutil/hwcontext.c
@@ -18,6 +18,7 @@
 
 #include "config.h"
 
+#include "avassert.h"
 #include "buffer.h"
 #include "common.h"
 #include "hwcontext.h"
@@ -788,6 +789,8 @@ fail:
 
 int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
 {
+AVBufferRef*orig_dst_frames = dst->hw_frames_ctx;
+enum AVPixelFormat orig_dst_fmt = dst->format;
 AVHWFramesContext *src_frames, *dst_frames;
 HWMapDescriptor *hwmap;
 int ret;
@@ -824,8 +827,10 @@ int av_hwframe_map(AVFrame *dst, const AVFrame *src, int 
flags)
 src_frames->internal->hw_type->map_from) {
 ret = src_frames->internal->hw_type->map_from(src_frames,
   dst, src, flags);
-if (ret != AVERROR(ENOSYS))
+if (ret >= 0)
 return ret;
+else if (ret != AVERROR(ENOSYS))
+goto fail;
 }
 }
 
@@ -836,12 +841,30 @@ int av_hwframe_map(AVFrame *dst, const AVFrame *src, int 
flags)
 dst_frames->internal->hw_type->map_to) {
 ret = dst_frames->internal->hw_type->map_to(dst_frames,
 dst, src, flags);
-if (ret != AVERROR(ENOSYS))
+if (ret >= 0)
 return ret;
+else if (ret != AVERROR(ENOSYS))
+goto fail;
 }
 }
 
 return AVERROR(ENOSYS);
+
+fail:
+// if the caller provided dst frames context, it should be preserved
+// by this function
+av_assert0(orig_dst_frames == NULL ||
+   orig_dst_frames == dst->hw_frames_ctx);
+
+// preserve user-provided dst frame fields, but clean
+// anything we might have set
+dst->hw_frames_ctx = NULL;
+av_frame_unref(dst);
+
+dst->hw_frames_ctx = orig_dst_frames;
+dst->format= orig_dst_fmt;
+
+return ret;
 }
 
 int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx,
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index 04d19d89c2..c18b7e1e8b 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -571,6 +571,10 @@ enum {
  * possible with the given arguments and hwframe setup, while other return
  * values indicate that it failed somehow.
  *
+ * On failure, the destination frame will be left blank, except for the
+ * hw_frames_ctx/format fields thay may have been set by the caller - those 
will
+ * be preserved as they were.
+ *
  * @param dst Destination frame, to contain the mapping.
  * @param src Source frame, to be mapped.
  * @param flags Some combination of AV_HWFRAME_MAP_* flags.
-- 
2.33.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 0/5] macos avdevice fixes and improvements

2022-01-19 Thread Romain Beauxis
This is a follow-up from a previous series of patches that fix, enhance and
cleanup support for audio and video input on macos in libavdevice. Due to
some important recent refactoring and addition, version is reset.

Patches:
  libavdevice/avfoundation.m: use setAudioSettings, extend supported formats
  libavdevice/avfoundation.m: Replace mutex-based concurrency handling in
avfoundation.m by a thread-safe fifo queue with maximum length
  libavdevice/avfoundation.m: Allow to select devices by unique ID
  Use appropriate method for device discovery.
  Add AudioToolbox audio input device.

 configure|   5 ++
 doc/indevs.texi  |  50 +++-
 libavdevice/Makefile |   1 +
 libavdevice/alldevices.c |   1 +
 libavdevice/audiotoolbox_dec.m (new) | 466
+++
 libavdevice/avfoundation.m   | 548
-
 6 files changed, 781 insertions(+), 290 deletions(-)
 create mode 100644 libavdevice/audiotoolbox_dec.m
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 1/5] libavdevice/avfoundation.m: use setAudioSettings, extend supported formats

2022-01-19 Thread Romain Beauxis
This patch switches the logic around audio settings to let the caller drive the 
format.

After experimenting with the AudioConverter, we realized that, even when 
adhering to a strict implementation of the documented API, we were still 
getting errors during conversions. The input device would randomly change from 
e.g. s32le to s24le between restarts and error out on conversion (using a 
freshly initialized converter).

Using setAudioSettings allow the OS to drive audio conversion internally and 
pick whatever appropriate settings for the audio device. This has been working 
very well and is also the way AVFoundation audio input is setup in videolan.

--- Begin Message ---
From fd30f651bdaafe812b5cdc022ef3e4ebd74b6727 Mon Sep 17 00:00:00 2001
From: Romain Beauxis 
Date: Mon, 29 Nov 2021 08:46:05 -0600
Subject: [PATCH] libavdevice/avfoundation.m: use setAudioSettings, extend
 supported formats
X-Unsent: 1
To: ffmpeg-devel@ffmpeg.org

This fixes: https://trac.ffmpeg.org/ticket/9502

Signed-off-by: Romain Beauxis 
---
 libavdevice/avfoundation.m | 206 -
 1 file changed, 63 insertions(+), 143 deletions(-)

diff --git a/libavdevice/avfoundation.m b/libavdevice/avfoundation.m
index 0cd6e646d5..77c6e68763 100644
--- a/libavdevice/avfoundation.m
+++ b/libavdevice/avfoundation.m
@@ -93,6 +93,11 @@
 AVRational  framerate;
 int width, height;
 
+int channels;
+int big_endian;
+int sample_rate;
+enum AVSampleFormat sample_format;
+
 int capture_cursor;
 int capture_mouse_clicks;
 int capture_raw_data;
@@ -111,17 +116,6 @@
 
 int num_video_devices;
 
-int audio_channels;
-int audio_bits_per_sample;
-int audio_float;
-int audio_be;
-int audio_signed_integer;
-int audio_packed;
-int audio_non_interleaved;
-
-int32_t *audio_buffer;
-int audio_buffer_size;
-
 enum AVPixelFormat pixel_format;
 
 AVCaptureSession *capture_session;
@@ -298,14 +292,6 @@ static void destroy_context(AVFContext* ctx)
 ctx->audio_output= NULL;
 ctx->avf_delegate= NULL;
 ctx->avf_audio_delegate = NULL;
-
-av_freep(&ctx->audio_buffer);
-
-pthread_mutex_destroy(&ctx->frame_lock);
-
-if (ctx->current_frame) {
-CFRelease(ctx->current_frame);
-}
 }
 
 static void parse_device_name(AVFormatContext *s)
@@ -671,88 +657,62 @@ static int get_video_config(AVFormatContext *s)
 static int get_audio_config(AVFormatContext *s)
 {
 AVFContext *ctx = (AVFContext*)s->priv_data;
-CMFormatDescriptionRef format_desc;
-AVStream* stream = avformat_new_stream(s, NULL);
+AVStream* stream;
+int bits_per_sample, is_float;
 
-if (!stream) {
-return 1;
-}
+enum AVCodecID codec_id = av_get_pcm_codec(ctx->sample_format, 
ctx->big_endian);
 
-// Take stream info from the first frame.
-while (ctx->audio_frames_captured < 1) {
-CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES);
+if (codec_id == AV_CODEC_ID_NONE) {
+   av_log(ctx, AV_LOG_ERROR, "Error: invalid sample format!\n");
+   return AVERROR(EINVAL);
 }
 
-lock_frames(ctx);
-
-ctx->audio_stream_index = stream->index;
-
-avpriv_set_pts_info(stream, 64, 1, avf_time_base);
-
-format_desc = CMSampleBufferGetFormatDescription(ctx->current_audio_frame);
-const AudioStreamBasicDescription *basic_desc = 
CMAudioFormatDescriptionGetStreamBasicDescription(format_desc);
+switch (ctx->sample_format) {
+case AV_SAMPLE_FMT_S16:
+bits_per_sample = 16;
+is_float = 0;
+break;
+case AV_SAMPLE_FMT_S32:
+bits_per_sample = 32;
+is_float = 0;
+break;
+case AV_SAMPLE_FMT_FLT:
+bits_per_sample = 32;
+is_float = 1;
+break;
+default:
+av_log(ctx, AV_LOG_ERROR, "Error: invalid sample format!\n");
+unlock_frames(ctx);
+return AVERROR(EINVAL);
+}
 
-if (!basic_desc) {
+[ctx->audio_output setAudioSettings:@{
+AVFormatIDKey:   @(kAudioFormatLinearPCM),
+AVLinearPCMBitDepthKey:  @(bits_per_sample),
+AVLinearPCMIsFloatKey:   @(is_float),
+AVLinearPCMIsBigEndianKey:   @(ctx->big_endian),
+AVNumberOfChannelsKey:   @(ctx->channels),
+AVLinearPCMIsNonInterleaved: @NO,
+AVSampleRateKey: @(ctx->sample_rate)
+}];
+
+stream = avformat_new_stream(s, NULL);
+if (!stream) {
 unlock_frames(ctx);
-av_log(s, AV_LOG_ERROR, "audio format not available\n");
-return 1;
+return -1;
 }
 
+avpriv_set_pts_info(stream, 64, 1, avf_time_base);
+
 stream->codecpar->codec_type = AVMED

Re: [FFmpeg-devel] [PATCH 1/5] libavdevice/avfoundation.m: use setAudioSettings, extend supported formats

2022-01-19 Thread Marvin Scholz

On 19 Jan 2022, at 15:23, Romain Beauxis wrote:

This patch switches the logic around audio settings to let the caller 
drive the format.


Hi,
just a quick technical feedback, with the patch sent as attachment it 
now finally applies

fine for me, thanks!



After experimenting with the AudioConverter, we realized that, even 
when adhering to a strict implementation of the documented API, we 
were still getting errors during conversions. The input device would 
randomly change from e.g. s32le to s24le between restarts and error 
out on conversion (using a freshly initialized converter).


Using setAudioSettings allow the OS to drive audio conversion 
internally and pick whatever appropriate settings for the audio 
device. This has been working very well and is also the way 
AVFoundation audio input is setup in videolan.

___
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/5] libavdevice/avfoundation.m: use setAudioSettings, extend supported formats

2022-01-19 Thread Andreas Rheinhardt
Romain Beauxis:
> This patch switches the logic around audio settings to let the caller drive 
> the 
> format.
> 
> After experimenting with the AudioConverter, we realized that, even when 
> adhering to a strict implementation of the documented API, we were still 
> getting 
> errors during conversions. The input device would randomly change from e.g. 
> s32le to s24le between restarts and error out on conversion (using a freshly 
> initialized converter).
> 
> Using setAudioSettings allow the OS to drive audio conversion internally and 
> pick whatever appropriate settings for the audio device. This has been 
> working 
> very well and is also the way AVFoundation audio input is setup in videolan.
> 

Your mail is broken: we don't want patches as eml; instead you should
attach what git format-patch produces. Or you can use git send-email
directly.

- Andreas
___
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/5] libavdevice/avfoundation.m: use setAudioSettings, extend supported formats

2022-01-19 Thread Gyan Doshi



On 2022-01-19 07:53 pm, Romain Beauxis wrote:

This patch switches the logic around audio settings to let the caller drive the 
format.

After experimenting with the AudioConverter, we realized that, even when 
adhering to a strict implementation of the documented API, we were still 
getting errors during conversions. The input device would randomly change from 
e.g. s32le to s24le between restarts and error out on conversion (using a 
freshly initialized converter).
 At present, the code uses the first frame to set attributes. If you 
wait for a few frames and then probe, the attributes are stable.


Regards,
Gyan
___
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/5] libavdevice/avfoundation.m: Replace mutex-based concurrency by a thread-safe fifo queue with maximum length

2022-01-19 Thread Romain Beauxis
The existing implementation of avdevice input has issues in its concurrent 
model as it only allows for one shared frame between writing and reading 
threads. This means that, if reading thread gets late, frames get dropped, 
resulting in corrupted input.

This patch changes the concurrency logic to use a single shared queue for both 
video and audio frames. Previous version of the patch used separate queues for 
audio and video but this could cause synchronization issues.

In order to avoid dropping initial audio frames, the video configuration logic 
is also changed to assume height/width as configured when opening the input 
device so as to not depend on the first video frame for it.

--- Begin Message ---
From d1a4c6e74ff589d9e59e1310a9afc9bc185382a1 Mon Sep 17 00:00:00 2001
From: Romain Beauxis 
Date: Sun, 12 Dec 2021 17:29:27 -0600
Subject: [PATCH] libavdevice/avfoundation.m: Replace mutex-based concurrency
 handling in avfoundation.m by a thread-safe fifo queue with maximum length
X-Unsent: 1
To: ffmpeg-devel@ffmpeg.org

* Use a shared CMSimpleQueueEnqueue with maximum length to queue and process 
incoming audio and video frames.
* Simplify video configuration to avoid consuming first frame.
* Log avfoundation errors.
* Use AVERROR_EXTERNAL instead of AVERROR(EIO) in avfoundation errors.

Signed-off-by: Romain Beauxis 
---
 libavdevice/avfoundation.m | 227 +
 1 file changed, 101 insertions(+), 126 deletions(-)

diff --git a/libavdevice/avfoundation.m b/libavdevice/avfoundation.m
index 77c6e68763..e6f64b35b8 100644
--- a/libavdevice/avfoundation.m
+++ b/libavdevice/avfoundation.m
@@ -26,7 +26,7 @@
  */
 
 #import 
-#include 
+#import 
 
 #include "libavutil/channel_layout.h"
 #include "libavutil/pixdesc.h"
@@ -39,6 +39,13 @@
 #include "libavutil/imgutils.h"
 #include "avdevice.h"
 
+static void av_log_avfoundation(void *s, int lvl, const char *str, OSStatus 
err) {
+NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+av_log(s, lvl, "AVFoundation: %s, %s\n", str,
+[[[NSError errorWithDomain:NSOSStatusErrorDomain code:err 
userInfo:nil] localizedDescription] UTF8String]);
+[pool release];
+}
+
 static const int avf_time_base = 100;
 
 static const AVRational avf_time_base_q = {
@@ -84,9 +91,6 @@
 {
 AVClass*class;
 
-int frames_captured;
-int audio_frames_captured;
-pthread_mutex_t frame_lock;
 id  avf_delegate;
 id  avf_audio_delegate;
 
@@ -121,8 +125,9 @@
 AVCaptureSession *capture_session;
 AVCaptureVideoDataOutput *video_output;
 AVCaptureAudioDataOutput *audio_output;
-CMSampleBufferRef current_frame;
-CMSampleBufferRef current_audio_frame;
+
+CMSimpleQueueRef  frames_queue;
+int   max_frames;
 
 AVCaptureDevice  *observed_device;
 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
@@ -131,16 +136,6 @@
 int  observed_quit;
 } AVFContext;
 
-static void lock_frames(AVFContext* ctx)
-{
-pthread_mutex_lock(&ctx->frame_lock);
-}
-
-static void unlock_frames(AVFContext* ctx)
-{
-pthread_mutex_unlock(&ctx->frame_lock);
-}
-
 /** FrameReciever class - delegate for AVCaptureSession
  */
 @interface AVFFrameReceiver : NSObject
@@ -218,17 +213,13 @@ - (void)  captureOutput:(AVCaptureOutput *)captureOutput
   didOutputSampleBuffer:(CMSampleBufferRef)videoFrame
  fromConnection:(AVCaptureConnection *)connection
 {
-lock_frames(_context);
+OSStatus ret = CMSimpleQueueEnqueue(_context->frames_queue, videoFrame);
 
-if (_context->current_frame != nil) {
-CFRelease(_context->current_frame);
+if (ret != noErr) {
+  av_log_avfoundation(_context, AV_LOG_DEBUG, "Error while queueing video 
frame", ret);
 }
 
-_context->current_frame = (CMSampleBufferRef)CFRetain(videoFrame);
-
-unlock_frames(_context);
-
-++_context->frames_captured;
+CFRetain(videoFrame);
 }
 
 @end
@@ -262,17 +253,13 @@ - (void)  captureOutput:(AVCaptureOutput *)captureOutput
   didOutputSampleBuffer:(CMSampleBufferRef)audioFrame
  fromConnection:(AVCaptureConnection *)connection
 {
-lock_frames(_context);
+OSStatus ret = CMSimpleQueueEnqueue(_context->frames_queue, audioFrame);
 
-if (_context->current_audio_frame != nil) {
-CFRelease(_context->current_audio_frame);
+if (ret != noErr) {
+  av_log_avfoundation(_context, AV_LOG_DEBUG, "Error while queueing audio 
frame", ret);
 }
 
-_context->current_audio_frame = (CMSampleBufferRef)CFRetain(audioFrame);
-
-unlock_frames(_context);
-
-++_context->audio_frames_captured;
+CFRetain(audioFrame);
 }
 
 @end
@@ -287,6 +274,19 @@ static void destroy_context(AVFContext* ctx)
 [ctx->avf_delegaterelease];
 [ctx->avf_audio_delegate release];
 
+CMSampleBufferRef frame;
+
+if (ctx->frames_queue) {
+

[FFmpeg-devel] [PATCH 3/5] libavdevice/avfoundation.m: Allow to select devices by unique ID

2022-01-19 Thread Romain Beauxis
This patch changes the logic around device selection to allow to use a static, 
machine-readable unique ID when selecting devices. Device names depends on 
locale settings and device index can change when plugging/unplugging devices.

--- Begin Message ---
From bf72d48c846f5116866ec588fc0ee54a2c354e87 Mon Sep 17 00:00:00 2001
From: Romain Beauxis 
Date: Mon, 13 Dec 2021 09:14:50 -0600
Subject: [PATCH] libavdevice/avfoundation.m: Allow to select devices by unique
 ID
X-Unsent: 1
To: ffmpeg-devel@ffmpeg.org

Signed-off-by: Romain Beauxis 
---
 doc/indevs.texi|  6 ++--
 libavdevice/avfoundation.m | 72 +-
 2 files changed, 60 insertions(+), 18 deletions(-)

diff --git a/doc/indevs.texi b/doc/indevs.texi
index 9d8020311a..858c0fa4e4 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -114,7 +114,7 @@ The input filename has to be given in the following syntax:
 -i "[[VIDEO]:[AUDIO]]"
 @end example
 The first entry selects the video input while the latter selects the audio 
input.
-The stream has to be specified by the device name or the device index as shown 
by the device list.
+The stream has to be specified by the device name, index or ID as shown by the 
device list.
 Alternatively, the video and/or audio input device can be chosen by index 
using the
 @option{
 -video_device_index 
@@ -127,7 +127,9 @@ and/or
 device name or index given in the input filename.
 
 All available devices can be enumerated by using @option{-list_devices true}, 
listing
-all device names and corresponding indices.
+all device names, corresponding indices and IDs, when available. Device name 
can be 
+tricky to use when localized and device index can change when devices are 
plugged or unplugged. A device
+hash, when available, uniquely identifies a device and should not change over 
time.
 
 There are two device name aliases:
 @table @code
diff --git a/libavdevice/avfoundation.m b/libavdevice/avfoundation.m
index e6f64b35b8..5d013cc0eb 100644
--- a/libavdevice/avfoundation.m
+++ b/libavdevice/avfoundation.m
@@ -39,6 +39,8 @@
 #include "libavutil/imgutils.h"
 #include "avdevice.h"
 
+#define CLEANUP_DEVICE_ID(s) [[s stringByReplacingOccurrencesOfString:@":" 
withString:@"."] UTF8String]
+
 static void av_log_avfoundation(void *s, int lvl, const char *str, OSStatus 
err) {
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 av_log(s, lvl, "AVFoundation: %s, %s\n", str,
@@ -710,21 +712,23 @@ static int avf_read_header(AVFormatContext *s)
 int index = 0;
 av_log(ctx, AV_LOG_INFO, "AVFoundation video devices:\n");
 for (AVCaptureDevice *device in devices) {
-const char *name = [[device localizedName] UTF8String];
-index= [devices indexOfObject:device];
-av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name);
+const char *name = [[device localizedName] UTF8String];
+const char *uniqueId = CLEANUP_DEVICE_ID([device uniqueID]);
+index= [devices indexOfObject:device];
+av_log(ctx, AV_LOG_INFO, "[%d] %s (ID: %s)\n", index, name, 
uniqueId);
 }
 for (AVCaptureDevice *device in devices_muxed) {
-const char *name = [[device localizedName] UTF8String];
-index= [devices count] + [devices_muxed 
indexOfObject:device];
-av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name);
+const char *name = [[device localizedName] UTF8String];
+const char *uniqueId = CLEANUP_DEVICE_ID([device uniqueID]);
+index= [devices count] + [devices_muxed 
indexOfObject:device];
+av_log(ctx, AV_LOG_INFO, "[%d] %s (ID: %s)\n", index, name, 
uniqueId);
 }
 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
 if (num_screens > 0) {
 CGDirectDisplayID screens[num_screens];
 CGGetActiveDisplayList(num_screens, screens, &num_screens);
 for (int i = 0; i < num_screens; i++) {
-av_log(ctx, AV_LOG_INFO, "[%d] Capture screen %d\n", 
ctx->num_video_devices + i, i);
+av_log(ctx, AV_LOG_INFO, "[%d] Capture screen %d (ID: 
AvfilterAvfoundationCaptureScreen%d)\n", ctx->num_video_devices + i, i, 
screens[i]);
 }
 }
 #endif
@@ -732,9 +736,10 @@ static int avf_read_header(AVFormatContext *s)
 av_log(ctx, AV_LOG_INFO, "AVFoundation audio devices:\n");
 devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio];
 for (AVCaptureDevice *device in devices) {
-const char *name = [[device localizedName] UTF8String];
-int index  = [devices indexOfObject:device];
-av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name);
+const char *name = [[device localizedName] UTF8String];
+const char *uniqueId = CLEANUP_DEVICE_ID([device uniqueID]);
+int index  

[FFmpeg-devel] [PATCH 4/5] Use appropriate method for device discovery.

2022-01-19 Thread Romain Beauxis
This adds support for the non-deprecated methods for selecting devices, when 
available.

--- Begin Message ---
From c42612b455289622edb638436b1892e43279d8ac Mon Sep 17 00:00:00 2001
From: Romain Beauxis 
Date: Fri, 14 Jan 2022 10:06:08 -0600
Subject: [PATCH] Use appropriate method for device discovery.
X-Unsent: 1
To: ffmpeg-devel@ffmpeg.org

Signed-off-by: Romain Beauxis 
---
 libavdevice/avfoundation.m | 77 --
 1 file changed, 57 insertions(+), 20 deletions(-)

diff --git a/libavdevice/avfoundation.m b/libavdevice/avfoundation.m
index 5d013cc0eb..03ec49df86 100644
--- a/libavdevice/avfoundation.m
+++ b/libavdevice/avfoundation.m
@@ -27,6 +27,7 @@
 
 #import 
 #import 
+#include 
 
 #include "libavutil/channel_layout.h"
 #include "libavutil/pixdesc.h"
@@ -698,8 +699,34 @@ static int avf_read_header(AVFormatContext *s)
 AVCaptureDevice *video_device = nil;
 AVCaptureDevice *audio_device = nil;
 // Find capture device
-NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
-NSArray *devices_muxed = [AVCaptureDevice 
devicesWithMediaType:AVMediaTypeMuxed];
+#if defined(__MAC_10_15) || (TARGET_OS_IPHONE && defined(__IPHONE_10_0))
+   AVCaptureDeviceDiscoverySession *discoverySession =
+[AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[
+#if TARGET_OS_IPHONE
+ 
AVCaptureDeviceTypeBuiltInDualCamera,
+ 
AVCaptureDeviceTypeBuiltInDualWideCamera,
+ 
AVCaptureDeviceTypeBuiltInUltraWideCamera,
+ 
AVCaptureDeviceTypeBuiltInTrueDepthCamera,
+ 
AVCaptureDeviceTypeBuiltInTelephotoCamera,
+#endif
+ 
AVCaptureDeviceTypeBuiltInWideAngleCamera,
+ 
AVCaptureDeviceTypeExternalUnknown
+ ]
+ mediaType:NULL
+ 
position:AVCaptureDevicePositionUnspecified];
+
+   NSMutableArray *devices   = [NSMutableArray array];
+   NSMutableArray *devices_muxed = [NSMutableArray array];
+   for (AVCaptureDevice *device in [discoverySession devices]) {
+   if ([device hasMediaType:AVMediaTypeVideo])
+   [devices addObject:device];
+   else if ([device hasMediaType:AVMediaTypeMuxed])
+   [devices_muxed addObject:device];
+   }
+#else
+   NSArray *devices = [AVCaptureDevice 
devicesWithMediaType:AVMediaTypeVideo];
+   NSArray *devices_muxed = [AVCaptureDevice 
devicesWithMediaType:AVMediaTypeMuxed];
+#endif
 
 ctx->num_video_devices = [devices count] + [devices_muxed count];
 
@@ -707,6 +734,21 @@ static int avf_read_header(AVFormatContext *s)
 CGGetActiveDisplayList(0, NULL, &num_screens);
 #endif
 
+NSArray *audio_devices;
+#if defined(__MAC_10_15) || (TARGET_OS_IPHONE && defined(__IPHONE_10_0))
+discoverySession =
+[AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[
+ 
AVCaptureDeviceTypeBuiltInMicrophone,
+ AVCaptureDeviceTypeExternalUnknown
+ ]
+ mediaType:AVMediaTypeAudio
+ 
position:AVCaptureDevicePositionUnspecified];
+
+audio_devices = [discoverySession devices];
+#else
+audio_devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio];
+#endif
+
 // List devices if requested
 if (ctx->list_devices) {
 int index = 0;
@@ -734,8 +776,7 @@ static int avf_read_header(AVFormatContext *s)
 #endif
 
 av_log(ctx, AV_LOG_INFO, "AVFoundation audio devices:\n");
-devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio];
-for (AVCaptureDevice *device in devices) {
+for (AVCaptureDevice *device in audio_devices) {
 const char *name = [[device localizedName] UTF8String];
 const char *uniqueId = CLEANUP_DEVICE_ID([device uniqueID]);
 int index= [devices indexOfObject:device];
@@ -885,9 +926,7 @@ static int avf_read_header(AVFormatContext *s)
 
 // get audio device
 if (ctx->audio_device_index >= 0) {
-NSArray *devices = [AVCaptureDevice 
devicesWithMediaType:AVMediaTypeAudio];
-
-if (ctx->audio_device_index >= [devices count]) {
+if (ctx->audio_device_index >= [audio_devices count]) {
 av_log(ctx, AV_LOG_ERROR, "Invalid audio device index\n");
 goto fail;
 }
@@ -898,22 +937,20 @@ static int avf_read_header(AVFormatContext *s)
 if (!strncmp(ctx->audio_filename, "default", 7)) {
   

[FFmpeg-devel] [PATCH 5/5] Add AudioToolbox audio input device.

2022-01-19 Thread Romain Beauxis
This patch adds support for a new, audio-specific input device using the 
documented and battle-tested AUHAL input. This provides a pendant to the 
AudioToolbox audio-only output.

A couple of advantages for this:
* It avoids a lot of the complexity of supporting audio and video in a single 
input
* The AUHAL API seems tested, documented and robust
* This implementation hopefully gives good control over audio latency and also 
minimizes data copy

--- Begin Message ---
From 803e1aa52018bdac0a448be255f645ca447273e9 Mon Sep 17 00:00:00 2001
From: Romain Beauxis 
Date: Tue, 18 Jan 2022 16:29:59 -0600
Subject: [PATCH] Add AudioToolbox audio input device.
X-Unsent: 1
To: ffmpeg-devel@ffmpeg.org

Signed-off-by: Romain Beauxis 
---
 configure  |   5 +
 doc/indevs.texi|  44 
 libavdevice/Makefile   |   1 +
 libavdevice/alldevices.c   |   1 +
 libavdevice/audiotoolbox_dec.m | 466 +
 5 files changed, 517 insertions(+)
 create mode 100644 libavdevice/audiotoolbox_dec.m

diff --git a/configure b/configure
index 1413122d87..80e39aae44 100755
--- a/configure
+++ b/configure
@@ -204,6 +204,7 @@ External library support:
   --disable-avfoundation   disable Apple AVFoundation framework [autodetect]
   --enable-avisynthenable reading of AviSynth script files [no]
   --disable-bzlib  disable bzlib [autodetect]
+  --disable-coremedia  disable Apple CoreMedia framework [autodetect]
   --disable-coreimage  disable Apple CoreImage framework [autodetect]
   --enable-chromaprint enable audio fingerprinting with chromaprint [no]
   --enable-frei0r  enable frei0r video filtering [no]
@@ -1750,6 +1751,7 @@ EXTERNAL_AUTODETECT_LIBRARY_LIST="
 appkit
 avfoundation
 bzlib
+coremedia
 coreimage
 iconv
 libxcb
@@ -3493,6 +3495,8 @@ alsa_outdev_deps="alsa"
 avfoundation_indev_deps="avfoundation corevideo coremedia pthreads"
 avfoundation_indev_suggest="coregraphics applicationservices"
 avfoundation_indev_extralibs="-framework Foundation"
+audiotoolbox_indev_deps="coremedia audiotoolbox"
+audiotoolbox_indev_extralibs="-framework CoreMedia -framework AudioToolbox"
 audiotoolbox_outdev_deps="audiotoolbox pthreads"
 audiotoolbox_outdev_extralibs="-framework AudioToolbox -framework CoreAudio"
 bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h 
dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h"
@@ -6340,6 +6344,7 @@ check_lib camera2ndk "stdbool.h stdint.h 
camera/NdkCameraManager.h" ACameraManag
 enabled appkit   && check_apple_framework AppKit
 enabled audiotoolbox && check_apple_framework AudioToolbox
 enabled avfoundation && check_apple_framework AVFoundation
+enabled coremedia&& check_apple_framework CoreMedia
 enabled coreimage&& check_apple_framework CoreImage
 enabled metal&& check_apple_framework Metal
 enabled videotoolbox && check_apple_framework VideoToolbox
diff --git a/doc/indevs.texi b/doc/indevs.texi
index 858c0fa4e4..30a91d304f 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -103,6 +103,50 @@ Set the maximum number of frames to buffer. Default is 5.
 
 @end table
 
+@section AudioToolbox
+
+AudioToolbox input device.
+
+Allows native input from CoreAudio devices on OSX.
+
+All available devices can be enumerated by using @option{-list_devices true}, 
listing
+all device names, and corresponding unique ID.
+
+@subsection Options
+
+AudioToolbox supports the following options:
+
+@table @option
+
+@item channels
+Set the number of channels. Default is device's default.
+
+@item frames_queue_length
+Maximum of buffers in the input queue
+
+@item buffer_frame_size
+Buffer frame size, gouverning internal latency
+
+@item big_endian
+Return big endian samples
+
+@item sample_format
+Sample format
+
+@end table
+
+@subsection Examples
+
+@itemize
+
+@item
+Print the list of supported devices
+@example
+$ ffmpeg -f audiotoolbox -list_devices true -i ""
+@end example
+
+@end itemize
+
 @section avfoundation
 
 AVFoundation input device.
diff --git a/libavdevice/Makefile b/libavdevice/Makefile
index 53efda0514..0c73255a21 100644
--- a/libavdevice/Makefile
+++ b/libavdevice/Makefile
@@ -14,6 +14,7 @@ OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o
 OBJS-$(CONFIG_ALSA_INDEV)+= alsa_dec.o alsa.o timefilter.o
 OBJS-$(CONFIG_ALSA_OUTDEV)   += alsa_enc.o alsa.o
 OBJS-$(CONFIG_ANDROID_CAMERA_INDEV)  += android_camera.o
+OBJS-$(CONFIG_AUDIOTOOLBOX_INDEV)+= audiotoolbox_dec.o
 OBJS-$(CONFIG_AUDIOTOOLBOX_OUTDEV)   += audiotoolbox.o
 OBJS-$(CONFIG_AVFOUNDATION_INDEV)+= avfoundation.o
 OBJS-$(CONFIG_BKTR_INDEV)+= bktr.o
diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c
index 22323a0a44..fbecdbb0b2 100644
--- a/libavdevice/alldevices.c
+++ b/libavdevice/alldevices.c
@@ -26,6 +26,7 @@ extern const AVInputFormat  ff_alsa_demuxer;
 extern const AVOutputFormat ff_alsa_muxer;
 extern c

Re: [FFmpeg-devel] [PATCH 1/5] libavdevice/avfoundation.m: use setAudioSettings, extend supported formats

2022-01-19 Thread Romain Beauxis
Le mer. 19 janv. 2022 à 08:31, Gyan Doshi  a écrit :
> On 2022-01-19 07:53 pm, Romain Beauxis wrote:
> > This patch switches the logic around audio settings to let the caller drive 
> > the format.
> >
> > After experimenting with the AudioConverter, we realized that, even when 
> > adhering to a strict implementation of the documented API, we were still 
> > getting errors during conversions. The input device would randomly change 
> > from e.g. s32le to s24le between restarts and error out on conversion 
> > (using a freshly initialized converter).
>   At present, the code uses the first frame to set attributes. If you
> wait for a few frames and then probe, the attributes are stable.

How is that supposed to work to get a full A/V stream? Discarding
initial audio frames results in data loss in audio-only input and
corrupted initial audio in A/V inputs.
___
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/5] libavdevice/avfoundation.m: use setAudioSettings, extend supported formats

2022-01-19 Thread Gyan Doshi



On 2022-01-19 08:44 pm, Romain Beauxis wrote:

Le mer. 19 janv. 2022 à 08:31, Gyan Doshi  a écrit :

On 2022-01-19 07:53 pm, Romain Beauxis wrote:

This patch switches the logic around audio settings to let the caller drive the 
format.

After experimenting with the AudioConverter, we realized that, even when 
adhering to a strict implementation of the documented API, we were still 
getting errors during conversions. The input device would randomly change from 
e.g. s32le to s24le between restarts and error out on conversion (using a 
freshly initialized converter).

   At present, the code uses the first frame to set attributes. If you
wait for a few frames and then probe, the attributes are stable.

How is that supposed to work to get a full A/V stream? Discarding
initial audio frames results in data loss in audio-only input and
corrupted initial audio in A/V inputs.


We're talking about around 5-6 packets, so ~100 ms. The streaming 
scenarios I worked on weren't sensitive to that amount of initial loss. 
YMMV.


Regards
Gyan
___
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/5] libavdevice/avfoundation.m: use setAudioSettings, extend supported formats

2022-01-19 Thread Romain Beauxis
Le mer. 19 janv. 2022 à 09:19, Gyan Doshi  a écrit :
> On 2022-01-19 08:44 pm, Romain Beauxis wrote:
> > Le mer. 19 janv. 2022 à 08:31, Gyan Doshi  a écrit :
> >> On 2022-01-19 07:53 pm, Romain Beauxis wrote:
> >>> This patch switches the logic around audio settings to let the caller 
> >>> drive the format.
> >>>
> >>> After experimenting with the AudioConverter, we realized that, even when 
> >>> adhering to a strict implementation of the documented API, we were still 
> >>> getting errors during conversions. The input device would randomly change 
> >>> from e.g. s32le to s24le between restarts and error out on conversion 
> >>> (using a freshly initialized converter).
> >>At present, the code uses the first frame to set attributes. If you
> >> wait for a few frames and then probe, the attributes are stable.
> > How is that supposed to work to get a full A/V stream? Discarding
> > initial audio frames results in data loss in audio-only input and
> > corrupted initial audio in A/V inputs.
>
> We're talking about around 5-6 packets, so ~100 ms. The streaming
> scenarios I worked on weren't sensitive to that amount of initial loss.
> YMMV.

I see thanks. And what advantages does this method provide aside from
supporting 24 bit sample formats which are currently excluded from
these changes?
___
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] configure: link to libatomic when it's present

2022-01-19 Thread James Almer

On 1/19/2022 10:48 AM, Anton Khirnov wrote:

C11 atomics in some configurations (e.g. 64bit operations on ppc64 with
GCC) require linking to libatomic.

Fixes #9275
---
  configure | 25 -
  1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/configure b/configure
index 1413122d87..3059c154df 100755
--- a/configure
+++ b/configure
@@ -3794,20 +3794,20 @@ cws2fws_extralibs="zlib_extralibs"
  
  # libraries, in any order

  avcodec_deps="avutil"
-avcodec_suggest="libm"
+avcodec_suggest="libm stdatomic"
  avdevice_deps="avformat avcodec avutil"
-avdevice_suggest="libm"
+avdevice_suggest="libm stdatomic"
  avfilter_deps="avutil"
-avfilter_suggest="libm"
+avfilter_suggest="libm stdatomic"
  avformat_deps="avcodec avutil"
-avformat_suggest="libm network zlib"
-avutil_suggest="clock_gettime ffnvcodec libm libdrm libmfx opencl user32 vaapi 
vulkan videotoolbox corefoundation corevideo coremedia bcrypt"
+avformat_suggest="libm network zlib stdatomic"
+avutil_suggest="clock_gettime ffnvcodec libm libdrm libmfx opencl user32 vaapi 
vulkan videotoolbox corefoundation corevideo coremedia bcrypt stdatomic"
  postproc_deps="avutil gpl"
-postproc_suggest="libm"
+postproc_suggest="libm stdatomic"
  swresample_deps="avutil"
-swresample_suggest="libm libsoxr"
+swresample_suggest="libm libsoxr stdatomic"
  swscale_deps="avutil"
-swscale_suggest="libm"
+swscale_suggest="libm stdatomic"
  
  avcodec_extralibs="pthreads_extralibs iconv_extralibs dxva2_extralibs"

  avfilter_extralibs="pthreads_extralibs"
@@ -6324,7 +6324,14 @@ check_headers asm/types.h
  # it seems there are versions of clang in some distros that try to use the
  # gcc headers, which explodes for stdatomic
  # so we also check that atomics actually work here
-check_builtin stdatomic stdatomic.h "atomic_int foo, bar = ATOMIC_VAR_INIT(-1); 
atomic_store(&foo, 0); foo += bar"
+#
+# some configurations also require linking to libatomic, so try
+# both with -latomic and without
+for LATOMIC in "-latomic" ""; do
+check_builtin stdatomic stdatomic.h
 \
+"atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += 
bar"  \
+$LATOMIC && eval stdatomic_extralibs="\$LATOMIC" && break
+done


LGTM now, thanks.

  
  check_lib advapi32 "windows.h"RegCloseKey  -ladvapi32

  check_lib bcrypt   "windows.h bcrypt.h"   BCryptGenRandom  -lbcrypt &&

___
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/5] libavdevice/avfoundation.m: use setAudioSettings, extend supported formats

2022-01-19 Thread Gyan Doshi



On 2022-01-19 08:51 pm, Romain Beauxis wrote:

Le mer. 19 janv. 2022 à 09:19, Gyan Doshi  a écrit :

On 2022-01-19 08:44 pm, Romain Beauxis wrote:

Le mer. 19 janv. 2022 à 08:31, Gyan Doshi  a écrit :

On 2022-01-19 07:53 pm, Romain Beauxis wrote:

This patch switches the logic around audio settings to let the caller drive the 
format.

After experimenting with the AudioConverter, we realized that, even when 
adhering to a strict implementation of the documented API, we were still 
getting errors during conversions. The input device would randomly change from 
e.g. s32le to s24le between restarts and error out on conversion (using a 
freshly initialized converter).

At present, the code uses the first frame to set attributes. If you
wait for a few frames and then probe, the attributes are stable.

How is that supposed to work to get a full A/V stream? Discarding
initial audio frames results in data loss in audio-only input and
corrupted initial audio in A/V inputs.

We're talking about around 5-6 packets, so ~100 ms. The streaming
scenarios I worked on weren't sensitive to that amount of initial loss.
YMMV.

I see thanks. And what advantages does this method provide aside from
supporting 24 bit sample formats which are currently excluded from
these changes?


I was remarking on a way to avoid format changes post-initialization.
Not a comment on your patches.

Gyan
___
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/5] libavdevice/avfoundation.m: use setAudioSettings, extend supported formats

2022-01-19 Thread Romain Beauxis
Le mer. 19 janv. 2022 à 09:45, Gyan Doshi  a écrit :
> On 2022-01-19 08:51 pm, Romain Beauxis wrote:
> > Le mer. 19 janv. 2022 à 09:19, Gyan Doshi  a écrit :
> >> On 2022-01-19 08:44 pm, Romain Beauxis wrote:
> >>> Le mer. 19 janv. 2022 à 08:31, Gyan Doshi  a écrit :
>  On 2022-01-19 07:53 pm, Romain Beauxis wrote:
> > This patch switches the logic around audio settings to let the caller 
> > drive the format.
> >
> > After experimenting with the AudioConverter, we realized that, even 
> > when adhering to a strict implementation of the documented API, we were 
> > still getting errors during conversions. The input device would 
> > randomly change from e.g. s32le to s24le between restarts and error out 
> > on conversion (using a freshly initialized converter).
>  At present, the code uses the first frame to set attributes. If you
>  wait for a few frames and then probe, the attributes are stable.
> >>> How is that supposed to work to get a full A/V stream? Discarding
> >>> initial audio frames results in data loss in audio-only input and
> >>> corrupted initial audio in A/V inputs.
> >> We're talking about around 5-6 packets, so ~100 ms. The streaming
> >> scenarios I worked on weren't sensitive to that amount of initial loss.
> >> YMMV.
> > I see thanks. And what advantages does this method provide aside from
> > supporting 24 bit sample formats which are currently excluded from
> > these changes?
>
> I was remarking on a way to avoid format changes post-initialization.
> Not a comment on your patches.

For sure, and I appreciate the feedback.
___
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/5] libavdevice/avfoundation.m: use setAudioSettings, extend supported formats

2022-01-19 Thread Thilo Borgmann

Am 19.01.22 um 15:28 schrieb Andreas Rheinhardt:

Romain Beauxis:

This patch switches the logic around audio settings to let the caller drive the
format.

After experimenting with the AudioConverter, we realized that, even when
adhering to a strict implementation of the documented API, we were still getting
errors during conversions. The input device would randomly change from e.g.
s32le to s24le between restarts and error out on conversion (using a freshly
initialized converter).

Using setAudioSettings allow the OS to drive audio conversion internally and
pick whatever appropriate settings for the audio device. This has been working
very well and is also the way AVFoundation audio input is setup in videolan.



Your mail is broken: we don't want patches as eml; instead you should
attach what git format-patch produces. Or you can use git send-email
directly.


+1, please.

-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".


Re: [FFmpeg-devel] [PATCH 5/5] Add AudioToolbox audio input device.

2022-01-19 Thread Marvin Scholz



On 19 Jan 2022, at 15:42, Romain Beauxis wrote:

Hi, thanks for the patch. I've not done a full code review yet, just a 
few

initial remarks below:

This patch adds support for a new, audio-specific input device using 
the documented and battle-tested AUHAL input. This provides a pendant 
to the AudioToolbox audio-only output.


A couple of advantages for this:
* It avoids a lot of the complexity of supporting audio and video in a 
single input

* The AUHAL API seems tested, documented and robust
* This implementation hopefully gives good control over audio latency 
and also minimizes data copy

From: Romain Beauxis 
To: ffmpeg-devel@ffmpeg.org
Subject: [PATCH] Add AudioToolbox audio input device.
Date: 18. January 2022 at 23:29
Signed-off-by: Romain Beauxis 
---
 configure  |   5 +
 doc/indevs.texi|  44 
 libavdevice/Makefile   |   1 +
 libavdevice/alldevices.c   |   1 +
 libavdevice/audiotoolbox_dec.m | 466 
+

 5 files changed, 517 insertions(+)
 create mode 100644 libavdevice/audiotoolbox_dec.m

diff --git a/configure b/configure
index 1413122d87..80e39aae44 100755
--- a/configure
+++ b/configure
@@ -204,6 +204,7 @@ External library support:
   --disable-avfoundation   disable Apple AVFoundation framework 
[autodetect]
   --enable-avisynthenable reading of AviSynth script files 
[no]

   --disable-bzlib  disable bzlib [autodetect]
+  --disable-coremedia  disable Apple CoreMedia framework 
[autodetect]
   --disable-coreimage  disable Apple CoreImage framework 
[autodetect]
   --enable-chromaprint enable audio fingerprinting with 
chromaprint [no]

   --enable-frei0r  enable frei0r video filtering [no]
@@ -1750,6 +1751,7 @@ EXTERNAL_AUTODETECT_LIBRARY_LIST="
 appkit
 avfoundation
 bzlib
+coremedia
 coreimage
 iconv
 libxcb
@@ -3493,6 +3495,8 @@ alsa_outdev_deps="alsa"
 avfoundation_indev_deps="avfoundation corevideo coremedia pthreads"
 avfoundation_indev_suggest="coregraphics applicationservices"
 avfoundation_indev_extralibs="-framework Foundation"
+audiotoolbox_indev_deps="coremedia audiotoolbox"
+audiotoolbox_indev_extralibs="-framework CoreMedia -framework 
AudioToolbox"

 audiotoolbox_outdev_deps="audiotoolbox pthreads"
 audiotoolbox_outdev_extralibs="-framework AudioToolbox -framework 
CoreAudio"
 bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h 
dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h"
@@ -6340,6 +6344,7 @@ check_lib camera2ndk "stdbool.h stdint.h 
camera/NdkCameraManager.h" ACameraManag

 enabled appkit   && check_apple_framework AppKit
 enabled audiotoolbox && check_apple_framework AudioToolbox
 enabled avfoundation && check_apple_framework AVFoundation
+enabled coremedia&& check_apple_framework CoreMedia
 enabled coreimage&& check_apple_framework CoreImage
 enabled metal&& check_apple_framework Metal
 enabled videotoolbox && check_apple_framework VideoToolbox
diff --git a/doc/indevs.texi b/doc/indevs.texi
index 858c0fa4e4..30a91d304f 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -103,6 +103,50 @@ Set the maximum number of frames to buffer. 
Default is 5.


 @end table

+@section AudioToolbox
+
+AudioToolbox input device.
+
+Allows native input from CoreAudio devices on OSX.

Nit: Nowadays it's macOS instead of OSX


+
+All available devices can be enumerated by using 
@option{-list_devices true}, listing

+all device names, and corresponding unique ID.


Instead of adding another device that uses a custom list-devices option, 
could you
instead implement the .get_device_list callback? (See alsa or pulse 
modules for an
example) Then listing would work properly with the `ffmpeg -sources` 
command and

devices could be iterated over using the avdevice APIs as well.

(Ideally we would have that for AVFoundation too but its really hard now 
to do that

in a backwards compatible manner)


+
+@subsection Options
+
+AudioToolbox supports the following options:
+
+@table @option
+
+@item channels
+Set the number of channels. Default is device's default.
+
+@item frames_queue_length
+Maximum of buffers in the input queue
+
+@item buffer_frame_size
+Buffer frame size, gouverning internal latency
+
+@item big_endian
+Return big endian samples
+
+@item sample_format
+Sample format
+
+@end table
+
+@subsection Examples
+
+@itemize
+
+@item
+Print the list of supported devices
+@example
+$ ffmpeg -f audiotoolbox -list_devices true -i ""
+@end example
+
+@end itemize
+
 @section avfoundation

[…]
___
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 274/281] swresample: convert to new channel layout API

2022-01-19 Thread Andreas Rheinhardt
James Almer:
> Signed-off-by: James Almer 
> ---
>  libswresample/options.c |  33 +++-
>  libswresample/rematrix.c| 237 ++--
>  libswresample/rematrix_template.c   |   7 +-
>  libswresample/swresample.c  | 152 +++---
>  libswresample/swresample.h  |  63 

This header still contains many references to swr_alloc_set_opts().

>  libswresample/swresample_frame.c|  65 +++-
>  libswresample/swresample_internal.h |  10 +-
>  7 files changed, 445 insertions(+), 122 deletions(-)
> 
> diff --git a/libswresample/options.c b/libswresample/options.c
> index 6911709157..ffa27c590d 100644
> --- a/libswresample/options.c
> +++ b/libswresample/options.c
> @@ -34,12 +34,19 @@
>  
>  #define OFFSET(x) offsetof(SwrContext,x)
>  #define PARAM AV_OPT_FLAG_AUDIO_PARAM
> +#define DEPREC AV_OPT_FLAG_DEPRECATED
>  
>  static const AVOption options[]={
> -{"ich"  , "set input channel count" , 
> OFFSET(user_in_ch_count  ), AV_OPT_TYPE_INT, {.i64=0}, 0  
> , SWR_CH_MAX, PARAM},
> -{"in_channel_count" , "set input channel count" , 
> OFFSET(user_in_ch_count  ), AV_OPT_TYPE_INT, {.i64=0}, 0  
> , SWR_CH_MAX, PARAM},
> -{"och"  , "set output channel count", 
> OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0}, 0  
> , SWR_CH_MAX, PARAM},
> -{"out_channel_count", "set output channel count", 
> OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0}, 0  
> , SWR_CH_MAX, PARAM},
> +#if FF_API_OLD_CHANNEL_LAYOUT
> +{"ich"  , "set input channel count (Deprecated, use ichl)",
> +  
> OFFSET(user_in_ch_count  ), AV_OPT_TYPE_INT, {.i64=0}, 0  
> , SWR_CH_MAX, PARAM|DEPREC},
> +{"in_channel_count" , "set input channel count (Deprecated, use 
> in_chlayout)",
> +  
> OFFSET(user_in_ch_count  ), AV_OPT_TYPE_INT, {.i64=0}, 0  
> , SWR_CH_MAX, PARAM|DEPREC},
> +{"och"  , "set output channel count (Deprecated, use ochl)",
> +  
> OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0}, 0  
> , SWR_CH_MAX, PARAM|DEPREC},
> +{"out_channel_count", "set output channel count (Deprecated, use 
> out_chlayout)",
> +  
> OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0}, 0  
> , SWR_CH_MAX, PARAM|DEPREC},
> +#endif
>  {"uch"  , "set used channel count"  , 
> OFFSET(user_used_ch_count), AV_OPT_TYPE_INT, {.i64=0}, 0  
> , SWR_CH_MAX, PARAM},
>  {"used_channel_count"   , "set used channel count"  , 
> OFFSET(user_used_ch_count), AV_OPT_TYPE_INT, {.i64=0}, 0  
> , SWR_CH_MAX, PARAM},
>  {"isr"  , "set input sample rate"   , OFFSET( 
> in_sample_rate), AV_OPT_TYPE_INT  , {.i64=0 }, 0  , 
> INT_MAX   , PARAM},
> @@ -52,10 +59,20 @@ static const AVOption options[]={
>  {"out_sample_fmt"   , "set output sample format", 
> OFFSET(out_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, 
> -1   , INT_MAX, PARAM},
>  {"tsf"  , "set internal sample format"  , 
> OFFSET(user_int_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT , 
> {.i64=AV_SAMPLE_FMT_NONE}, -1   , INT_MAX, PARAM},
>  {"internal_sample_fmt"  , "set internal sample format"  , 
> OFFSET(user_int_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT , 
> {.i64=AV_SAMPLE_FMT_NONE}, -1   , INT_MAX, PARAM},
> -{"icl"  , "set input channel layout", 
> OFFSET(user_in_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0   }, 
> INT64_MIN, INT64_MAX , PARAM, "channel_layout"},
> -{"in_channel_layout", "set input channel layout", 
> OFFSET(user_in_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0   }, 
> INT64_MIN, INT64_MAX , PARAM, "channel_layout"},
> -{"ocl"  , "set output channel layout"   , 
> OFFSET(user_out_ch_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0   }, 
> INT64_MIN, INT64_MAX , PARAM, "channel_layout"},
> -{"out_channel_layout"   , "set output channel layout"   , 
> OFFSET(user_out_ch_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0   }, 
> INT64_MIN, INT64_MAX , PARAM, "channel_layout"},
> +#if FF_API_OLD_CHANNEL_LAYOUT
> +{"icl"  , "set input channel layout (Deprecated, use ichl)",
> +  
> OFFSET(user_in_ch_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0  }, 
> INT64_MIN, INT64_MAX, PARAM|DEPREC, "channel_layout"},
> +{"in_channel_layout", "set input channel layout (Deprecated, use 
> in_chlayout)",
> +   

Re: [FFmpeg-devel] [PATCH 274/281] swresample: convert to new channel layout API

2022-01-19 Thread James Almer

On 1/19/2022 2:20 PM, Andreas Rheinhardt wrote:

James Almer:

Signed-off-by: James Almer 
---
  libswresample/options.c |  33 +++-
  libswresample/rematrix.c| 237 ++--
  libswresample/rematrix_template.c   |   7 +-
  libswresample/swresample.c  | 152 +++---
  libswresample/swresample.h  |  63 


This header still contains many references to swr_alloc_set_opts().


Will change.




  libswresample/swresample_frame.c|  65 +++-
  libswresample/swresample_internal.h |  10 +-
  7 files changed, 445 insertions(+), 122 deletions(-)

diff --git a/libswresample/options.c b/libswresample/options.c
index 6911709157..ffa27c590d 100644
--- a/libswresample/options.c
+++ b/libswresample/options.c
@@ -34,12 +34,19 @@
  
  #define OFFSET(x) offsetof(SwrContext,x)

  #define PARAM AV_OPT_FLAG_AUDIO_PARAM
+#define DEPREC AV_OPT_FLAG_DEPRECATED
  
  static const AVOption options[]={

-{"ich"  , "set input channel count" , 
OFFSET(user_in_ch_count  ), AV_OPT_TYPE_INT, {.i64=0}, 0  , SWR_CH_MAX, 
PARAM},
-{"in_channel_count" , "set input channel count" , 
OFFSET(user_in_ch_count  ), AV_OPT_TYPE_INT, {.i64=0}, 0  , SWR_CH_MAX, 
PARAM},
-{"och"  , "set output channel count", 
OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0}, 0  , SWR_CH_MAX, 
PARAM},
-{"out_channel_count", "set output channel count", 
OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0}, 0  , SWR_CH_MAX, 
PARAM},
+#if FF_API_OLD_CHANNEL_LAYOUT
+{"ich"  , "set input channel count (Deprecated, use ichl)",
+  
OFFSET(user_in_ch_count  ), AV_OPT_TYPE_INT, {.i64=0}, 0
  , SWR_CH_MAX, PARAM|DEPREC},
+{"in_channel_count" , "set input channel count (Deprecated, use 
in_chlayout)",
+  
OFFSET(user_in_ch_count  ), AV_OPT_TYPE_INT, {.i64=0}, 0
  , SWR_CH_MAX, PARAM|DEPREC},
+{"och"  , "set output channel count (Deprecated, use ochl)",
+  
OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0}, 0
  , SWR_CH_MAX, PARAM|DEPREC},
+{"out_channel_count", "set output channel count (Deprecated, use 
out_chlayout)",
+  
OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0}, 0
  , SWR_CH_MAX, PARAM|DEPREC},
+#endif
  {"uch"  , "set used channel count"  , 
OFFSET(user_used_ch_count), AV_OPT_TYPE_INT, {.i64=0}, 0  , SWR_CH_MAX, 
PARAM},
  {"used_channel_count"   , "set used channel count"  , 
OFFSET(user_used_ch_count), AV_OPT_TYPE_INT, {.i64=0}, 0  , SWR_CH_MAX, 
PARAM},
  {"isr"  , "set input sample rate"   , OFFSET( 
in_sample_rate), AV_OPT_TYPE_INT  , {.i64=0 }, 0  , INT_MAX   , PARAM},
@@ -52,10 +59,20 @@ static const AVOption options[]={
  {"out_sample_fmt"   , "set output sample format", 
OFFSET(out_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1   , INT_MAX, PARAM},
  {"tsf"  , "set internal sample format"  , 
OFFSET(user_int_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1   , INT_MAX, 
PARAM},
  {"internal_sample_fmt"  , "set internal sample format"  , 
OFFSET(user_int_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1   , INT_MAX, 
PARAM},
-{"icl"  , "set input channel layout", OFFSET(user_in_ch_layout ), 
AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0   }, INT64_MIN, INT64_MAX , PARAM, "channel_layout"},
-{"in_channel_layout", "set input channel layout", OFFSET(user_in_ch_layout ), 
AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0   }, INT64_MIN, INT64_MAX , PARAM, "channel_layout"},
-{"ocl"  , "set output channel layout"   , OFFSET(user_out_ch_layout), 
AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0   }, INT64_MIN, INT64_MAX , PARAM, "channel_layout"},
-{"out_channel_layout"   , "set output channel layout"   , OFFSET(user_out_ch_layout), 
AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0   }, INT64_MIN, INT64_MAX , PARAM, "channel_layout"},
+#if FF_API_OLD_CHANNEL_LAYOUT
+{"icl"  , "set input channel layout (Deprecated, use ichl)",
+  OFFSET(user_in_ch_layout), 
AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0  }, INT64_MIN, INT64_MAX, PARAM|DEPREC, 
"channel_layout"},
+{"in_channel_layout", "set input channel layout (Deprecated, use 
in_chlayout)",
+  OFFSET(user_in_ch_layout), 
AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0  }, IN

Re: [FFmpeg-devel] [PATCH 001/289 v6] Add a new channel layout API

2022-01-19 Thread Andreas Rheinhardt
James Almer:
> From: Anton Khirnov 
> 
> The new API is more extensible and allows for custom layouts.
> More accurate information is exported, eg for decoders that do not
> set a channel layout, lavc will not make one up for them.
> 
> Deprecate the old API working with just uint64_t bitmasks.
> 
> Expanded and completed by Vittorio Giovara 
> and James Almer .
> Signed-off-by: Vittorio Giovara 
> Signed-off-by: James Almer 
> ---
> Changes since last version:
> 
> *av_channel_layout_from_string() and av_channel_layout_describe() now support
>  a "designation@name" syntax, effectively making both functions reciprocal
>  when there are custom names in some or all channels.
>  It's the syntax suggested by Marton and is both extensible if required and
>  not too ulgy in human readable output if the string is printed verbatim.
> 
> *av_channel_layout_index_from_string() and
>  av_channel_layout_channel_from_string() also support this syntax now.
> 
> I plan to push this version soon. Any extension to the syntax supported by 
> these
> helpers can be written by whoever needs it.

You forgot the examples and the tools; and ffplay. And do you really
intend for the deprecation warnings in ffmpeg_opt.c to stay?

- Andreas
___
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] avfilter/vf_libvmaf: update filter for libvmaf v2.0.0

2022-01-19 Thread Kyle Swanson
Hi,

On Thu, Jan 13, 2022 at 6:38 PM Kyle Swanson  wrote:
>
> Hi,
>
> On Mon, Jan 10, 2022 at 10:22 AM Andreas Rheinhardt
>  wrote:
> > 1. FFmpeg uses the ancient C90 rule that only allows variable
> > declarations at the beginning of a block (before all statements). You
> > should actually have received a compiler warning because of the above
> > code (unless you use Clang, which claims to support this type of
> > warning, yet doesn't).
> > 2. You jump over the initializion of str_copy if the dict allocation
> > fails and consequently you free an uninitialized string.
>
> New patch attached. Fixes all of the GCC -Wdeclaration-after-statement
> warnings. You're right, I didn't notice because I was building with
> Clang. Andreas, I will just wait for your LGTM before merging.
>
> Thanks,
> Kyle

Updated patch attached. Thank you to mkver for the mini review on IRC.
The `delimited_dict_parse` multi-delimiter corner case should be
sorted now.

Thanks,
Kyle


0001-avfilter-vf_libvmaf-update-filter-for-libvmaf-v2.0.0.patch
Description: Binary data
___
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] avfilter/adelay: Add command support

2022-01-19 Thread David Lacko
Adds command 'delays' to the adelay filter.
This command accepts same values as option with one difference, to apply
delay to all channels prefix 'all:' to the arguments is accepted.

Signed-off-by: David Lacko 
---
 libavfilter/af_adelay.c | 183 ++--
 1 file changed, 157 insertions(+), 26 deletions(-)

diff --git a/libavfilter/af_adelay.c b/libavfilter/af_adelay.c
index ed8a8ae739..1e13cf7fb0 100644
--- a/libavfilter/af_adelay.c
+++ b/libavfilter/af_adelay.c
@@ -31,6 +31,7 @@ typedef struct ChanDelay {
 int64_t delay;
 size_t delay_index;
 size_t index;
+unsigned int samples_size;
 uint8_t *samples;
 } ChanDelay;
 
@@ -48,13 +49,14 @@ typedef struct AudioDelayContext {
 
 void (*delay_channel)(ChanDelay *d, int nb_samples,
   const uint8_t *src, uint8_t *dst);
+int (*resize_channel_samples)(ChanDelay *d, int64_t new_delay);
 } AudioDelayContext;
 
 #define OFFSET(x) offsetof(AudioDelayContext, x)
 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
 
 static const AVOption adelay_options[] = {
-{ "delays", "set list of delays for each channel", OFFSET(delays), 
AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A },
+{ "delays", "set list of delays for each channel", OFFSET(delays), 
AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A | AV_OPT_FLAG_RUNTIME_PARAM },
 { "all","use last available delay for remained channels", OFFSET(all), 
AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, A },
 { NULL }
 };
@@ -96,11 +98,92 @@ DELAY(s32, int32_t, 0)
 DELAY(flt, float,   0)
 DELAY(dbl, double,  0)
 
+#define CHANGE_DELAY(name, type, fill) 
 \
+static int resize_samples_## name ##p(ChanDelay *d, int64_t new_delay) 
 \
+{  
 \
+type *samples = (type *)d->samples;
 \
+   
 \
+if (new_delay == d->delay) {   
 \
+return 0;  
 \
+}  
 \
+   
 \
+if (new_delay == 0) {  
 \
+av_freep(&d->samples); 
 \
+d->samples_size = 0;   
 \
+d->delay = 0;  
 \
+d->index = 0;  
 \
+return 0;  
 \
+}  
 \
+   
 \
+d->samples = av_fast_realloc(d->samples, &d->samples_size, new_delay * 
sizeof(type));   \
+if (!d->samples) { 
 \
+av_freep(samples); 
 \
+return AVERROR(ENOMEM);
 \
+}  
 \
+samples = (type *)d->samples;  
 \
+if (new_delay < d->delay) {
 \
+if (d->index > new_delay) {
 \
+d->index -= new_delay; 
 \
+memmove(samples, &samples[new_delay], d->index * sizeof(type));
 \
+} else if (d->delay_index > d->index) {
 \
+memmove(&samples[d->index], 
&samples[d->index+(d->delay-new_delay)],\
+(new_delay - d->index) * sizeof(type));
 \
+}  
 \
+d->delay_index = new_delay;  

Re: [FFmpeg-devel] [PATCH 109/281] mxf: convert to new channel layout API

2022-01-19 Thread Tomas Härdin
ons 2022-01-12 klockan 22:56 -0300 skrev James Almer:
> From: Vittorio Giovara 
> 
> Signed-off-by: Vittorio Giovara 
> Signed-off-by: Anton Khirnov 
> Signed-off-by: James Almer 
> ---
>  libavformat/mxfdec.c | 34 +-
>  libavformat/mxfenc.c | 20 +++-
>  2 files changed, 32 insertions(+), 22 deletions(-)

Looks OK with the reservation that I haven't looked at the new API

/Tomas

___
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] avfilter/adelay: Add command support

2022-01-19 Thread Andreas Rheinhardt
David Lacko:
> Adds command 'delays' to the adelay filter.
> This command accepts same values as option with one difference, to apply
> delay to all channels prefix 'all:' to the arguments is accepted.
> 
> Signed-off-by: David Lacko 
> ---
>  libavfilter/af_adelay.c | 183 ++--
>  1 file changed, 157 insertions(+), 26 deletions(-)
> 
> diff --git a/libavfilter/af_adelay.c b/libavfilter/af_adelay.c
> index ed8a8ae739..1e13cf7fb0 100644
> --- a/libavfilter/af_adelay.c
> +++ b/libavfilter/af_adelay.c
> @@ -31,6 +31,7 @@ typedef struct ChanDelay {
>  int64_t delay;
>  size_t delay_index;
>  size_t index;
> +unsigned int samples_size;
>  uint8_t *samples;
>  } ChanDelay;
>  
> @@ -48,13 +49,14 @@ typedef struct AudioDelayContext {
>  
>  void (*delay_channel)(ChanDelay *d, int nb_samples,
>const uint8_t *src, uint8_t *dst);
> +int (*resize_channel_samples)(ChanDelay *d, int64_t new_delay);
>  } AudioDelayContext;
>  
>  #define OFFSET(x) offsetof(AudioDelayContext, x)
>  #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
>  
>  static const AVOption adelay_options[] = {
> -{ "delays", "set list of delays for each channel", OFFSET(delays), 
> AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A },
> +{ "delays", "set list of delays for each channel", OFFSET(delays), 
> AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A | AV_OPT_FLAG_RUNTIME_PARAM },
>  { "all","use last available delay for remained channels", 
> OFFSET(all), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, A },
>  { NULL }
>  };
> @@ -96,11 +98,92 @@ DELAY(s32, int32_t, 0)
>  DELAY(flt, float,   0)
>  DELAY(dbl, double,  0)
>  
> +#define CHANGE_DELAY(name, type, fill)   
>\
> +static int resize_samples_## name ##p(ChanDelay *d, int64_t new_delay)   
>\
> +{
>\
> +type *samples = (type *)d->samples;  
>\
> + 
>\
> +if (new_delay == d->delay) { 
>\
> +return 0;
>\
> +}
>\
> + 
>\
> +if (new_delay == 0) {
>\
> +av_freep(&d->samples);   
>\
> +d->samples_size = 0; 
>\
> +d->delay = 0;
>\
> +d->index = 0;
>\
> +return 0;
>\
> +}
>\
> + 
>\
> +d->samples = av_fast_realloc(d->samples, &d->samples_size, new_delay * 
> sizeof(type));   \
> +if (!d->samples) {   
>\
> +av_freep(samples);   
>\

av_free(samples) or av_freep(&samples), but not av_freep(samples).
The typical way to write this is btw tmp = av_fast_realloc(buf,...) (in
your case samples = av_fast_realloc(d->samples, ...) with
av_freep(&d->samples); in the error branch and d->samples = samples in
the non-error-case.

> +return AVERROR(ENOMEM);  
>\
> +}
>\


___
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] libfdk-aacdec: Add an option for setting the decoder's DRC album mode

2022-01-19 Thread Martin Storsjö
---
 libavcodec/libfdk-aacdec.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/libavcodec/libfdk-aacdec.c b/libavcodec/libfdk-aacdec.c
index ffa1fdcce3..93b52023b0 100644
--- a/libavcodec/libfdk-aacdec.c
+++ b/libavcodec/libfdk-aacdec.c
@@ -56,6 +56,7 @@ typedef struct FDKAACDecContext {
 int drc_heavy;
 int drc_effect;
 int drc_cut;
+int album_mode;
 int level_limit;
 int output_delay;
 } FDKAACDecContext;
@@ -87,6 +88,10 @@ static const AVOption fdk_aac_dec_options[] = {
 #if FDKDEC_VER_AT_LEAST(3, 0) // 3.0.0
 { "drc_effect","Dynamic Range Control: effect type, where e.g. [0] is none 
and [6] is general",
  OFFSET(drc_effect), AV_OPT_TYPE_INT,   { .i64 = -1},  
-1, 8,   AD, NULL},
+#endif
+#if FDKDEC_VER_AT_LEAST(3, 1) // 3.1.0
+{ "album_mode","Dynamic Range Control: album mode, where [0] is off and 
[1] is on",
+ OFFSET(album_mode), AV_OPT_TYPE_INT,   { .i64 = -1},  
-1, 1,   AD, NULL},
 #endif
 { NULL }
 };
@@ -335,6 +340,15 @@ static av_cold int fdk_aac_decode_init(AVCodecContext 
*avctx)
 }
 #endif
 
+#if FDKDEC_VER_AT_LEAST(3, 1) // 3.1.0
+if (s->album_mode != -1) {
+if (aacDecoder_SetParam(s->handle, AAC_UNIDRC_ALBUM_MODE, 
s->album_mode) != AAC_DEC_OK) {
+av_log(avctx, AV_LOG_ERROR, "Unable to set album mode in the 
decoder\n");
+return AVERROR_UNKNOWN;
+}
+}
+#endif
+
 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
 
 s->decoder_buffer_size = DECODER_BUFFSIZE * DECODER_MAX_CHANNELS;
-- 
2.32.0 (Apple Git-132)

___
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] libfdk-aacdec: Flush delayed samples at the end

2022-01-19 Thread Martin Storsjö
Also trim off delay samples at the start instead of adjusting pts
to compensate for them; this avoids unwanted offsets if working
with raw samples without considering their pts.
---
 libavcodec/libfdk-aacdec.c | 80 +++---
 1 file changed, 65 insertions(+), 15 deletions(-)

diff --git a/libavcodec/libfdk-aacdec.c b/libavcodec/libfdk-aacdec.c
index 93b52023b0..d560e313ca 100644
--- a/libavcodec/libfdk-aacdec.c
+++ b/libavcodec/libfdk-aacdec.c
@@ -58,7 +58,11 @@ typedef struct FDKAACDecContext {
 int drc_cut;
 int album_mode;
 int level_limit;
-int output_delay;
+#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10
+int output_delay_set;
+int flush_samples;
+int delay_samples;
+#endif
 } FDKAACDecContext;
 
 
@@ -123,7 +127,12 @@ static int get_stream_info(AVCodecContext *avctx)
 avctx->sample_rate = info->sampleRate;
 avctx->frame_size  = info->frameSize;
 #if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10
-s->output_delay= info->outputDelay;
+if (!s->output_delay_set && info->outputDelay) {
+// Set this only once.
+s->flush_samples= info->outputDelay;
+s->delay_samples= info->outputDelay;
+s->output_delay_set = 1;
+}
 #endif
 
 for (i = 0; i < info->numChannels; i++) {
@@ -367,14 +376,31 @@ static int fdk_aac_decode_frame(AVCodecContext *avctx, 
void *data,
 int ret;
 AAC_DECODER_ERROR err;
 UINT valid = avpkt->size;
+UINT flags = 0;
+int input_offset = 0;
 
-err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid);
-if (err != AAC_DEC_OK) {
-av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err);
-return AVERROR_INVALIDDATA;
+if (avpkt->size) {
+err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid);
+if (err != AAC_DEC_OK) {
+av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err);
+return AVERROR_INVALIDDATA;
+}
+} else {
+#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10
+/* Handle decoder draining */
+if (s->flush_samples > 0) {
+flags |= AACDEC_FLUSH;
+} else {
+return AVERROR_EOF;
+}
+#else
+return AVERROR_EOF;
+#endif
 }
 
-err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) s->decoder_buffer, 
s->decoder_buffer_size / sizeof(INT_PCM), 0);
+err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) s->decoder_buffer,
+ s->decoder_buffer_size / sizeof(INT_PCM),
+ flags);
 if (err == AAC_DEC_NOT_ENOUGH_BITS) {
 ret = avpkt->size - valid;
 goto end;
@@ -390,16 +416,36 @@ static int fdk_aac_decode_frame(AVCodecContext *avctx, 
void *data,
 goto end;
 frame->nb_samples = avctx->frame_size;
 
+#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10
+if (flags & AACDEC_FLUSH) {
+// Only return the right amount of samples at the end; if calling the
+// decoder with AACDEC_FLUSH, it will keep returning frames 
indefinitely.
+frame->nb_samples = FFMIN(s->flush_samples, frame->nb_samples);
+av_log(s, AV_LOG_DEBUG, "Returning %d/%d delayed samples.\n",
+frame->nb_samples, s->flush_samples);
+s->flush_samples -= frame->nb_samples;
+} else {
+// Trim off samples from the start to compensate for extra decoder
+// delay. We could also just adjust the pts, but this avoids
+// including the extra samples in the output altogether.
+if (s->delay_samples) {
+int drop_samples = FFMIN(s->delay_samples, frame->nb_samples);
+av_log(s, AV_LOG_DEBUG, "Dropping %d/%d delayed samples.\n",
+drop_samples, s->delay_samples);
+s->delay_samples  -= drop_samples;
+frame->nb_samples -= drop_samples;
+input_offset = drop_samples * avctx->channels;
+if (frame->nb_samples <= 0)
+return 0;
+}
+}
+#endif
+
 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
 goto end;
 
-if (frame->pts != AV_NOPTS_VALUE)
-frame->pts -= av_rescale_q(s->output_delay,
-   (AVRational){1, avctx->sample_rate},
-   avctx->time_base);
-
-memcpy(frame->extended_data[0], s->decoder_buffer,
-   avctx->channels * avctx->frame_size *
+memcpy(frame->extended_data[0], s->decoder_buffer + input_offset,
+   avctx->channels * frame->nb_samples *
av_get_bytes_per_sample(avctx->sample_fmt));
 
 *got_frame_ptr = 1;
@@ -432,7 +478,11 @@ const AVCodec ff_libfdk_aac_decoder = {
 .decode = fdk_aac_decode_frame,
 .close  = fdk_aac_decode_close,
 .flush  = fdk_aac_decode_flush,
-.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
+.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_

Re: [FFmpeg-devel] [PATCH 001/289 v6] Add a new channel layout API

2022-01-19 Thread Marton Balint




On Tue, 18 Jan 2022, James Almer wrote:


From: Anton Khirnov 

The new API is more extensible and allows for custom layouts.
More accurate information is exported, eg for decoders that do not
set a channel layout, lavc will not make one up for them.

Deprecate the old API working with just uint64_t bitmasks.

Expanded and completed by Vittorio Giovara 
and James Almer .
Signed-off-by: Vittorio Giovara 
Signed-off-by: James Almer 
---
Changes since last version:

*av_channel_layout_from_string() and av_channel_layout_describe() now support
a "designation@name" syntax, effectively making both functions reciprocal
when there are custom names in some or all channels.
It's the syntax suggested by Marton and is both extensible if required and
not too ulgy in human readable output if the string is printed verbatim.

*av_channel_layout_index_from_string() and
av_channel_layout_channel_from_string() also support this syntax now.


I have two suggestions. None of them is actually blocking, but since they 
concern public syntax and API it might be better to decide now.


av_channel_layout_index_from_string() without "@" in the string matches 
both builtin names (designations) and custom names. I suggest for it to 
only match builtin names. If a user wants to match by custom name, "@name" 
may be specified without a designation. This keeps the two namespaces 
separate.


av_channel_layout_channel_from_string() is an API which is not used in the 
codebase. I am not enterely sure about its purpose, so maybe it should be 
removed for now, and only added later, if some code actually needs it.


Thanks,
Marton
___
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/6] avformat/mux: Remove assert based on faulty assumptions

2022-01-19 Thread Andreas Rheinhardt
This assert is based upon the wrong assumption that
the noninterleaved codepath is never used; if it is used,
max_interleave_delta is irrelevant. It furthermore
ignores audio_preload.

Signed-off-by: Andreas Rheinhardt 
---
 libavformat/mux.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libavformat/mux.c b/libavformat/mux.c
index c387f8ec6e..e34fd88f05 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -697,7 +697,6 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
 );
 }
 } else {
-av_assert2(pkt->dts == AV_NOPTS_VALUE || pkt->dts >= 0 || 
s->max_interleave_delta > 0);
 if (pkt->dts != AV_NOPTS_VALUE && pkt->dts < 0) {
 av_log(s, AV_LOG_WARNING,
 "Packets poorly interleaved, failed to avoid negative "
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 2/6] fate/matroska: Add test for avoiding negative timestamps

2022-01-19 Thread Andreas Rheinhardt
This tests the issue from tickets #4536, #5784;
the output of this test is currently broken.

Signed-off-by: Andreas Rheinhardt 
---
Now only performing codec copy.

 tests/fate/matroska.mak   | 17 +
 tests/ref/fate/matroska-avoid-negative-ts | 42 +++
 2 files changed, 59 insertions(+)
 create mode 100644 tests/ref/fate/matroska-avoid-negative-ts

diff --git a/tests/fate/matroska.mak b/tests/fate/matroska.mak
index 2fcac34d62..b65a76411b 100644
--- a/tests/fate/matroska.mak
+++ b/tests/fate/matroska.mak
@@ -90,6 +90,23 @@ FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL 
MOV_DEMUXER   \
+= fate-matroska-dovi-write-config7
 fate-matroska-dovi-write-config7: CMD = transcode mov 
$(TARGET_SAMPLES)/mov/dovi-p7.mp4 matroska "-map 0 -c copy -cues_to_front yes 
-reserve_index_space 40  -metadata_header_padding 64339" "-map 0 -c copy" "" 
"-show_entries stream_side_data_list"
 
+# This tests the scenario like tickets #4536, #5784 where
+# the first packet (with the overall lowest dts) is a video packet,
+# whereas an audio packet to be muxed later has the overall lowest pts
+# which happens to be negative and therefore needs to be shifted.
+# This is currently buggy (the timestamps of the video frames muxed
+# before the first audio frame are not shifted).
+# (-ss 1.09 ensures that a video frame has the lowest dts of all packets;
+# yet there is an audio packet with the overall lowest pts. output_ts_offset
+# makes the pts of the audio packet, but not the leading video packet negative
+# so that we run into the above issue.)
+FATE_MATROSKA-$(call ALLYES, FILE_PROTOCOL MPEGTS_DEMUXER MPEGVIDEO_PARSER  \
+ MPEG2VIDEO_DECODER EXTRACT_EXTRADATA_BSF   \
+ MP3FLOAT_DECODER MATROSKA_MUXER\
+ MATROSKA_DEMUXER FRAMECRC_MUXER PIPE_PROTOCOL) \
++= fate-matroska-avoid-negative-ts
+fate-matroska-avoid-negative-ts: CMD = transcode mpegts 
$(TARGET_SAMPLES)/mpeg2/t.mpg matroska "-c copy -ss 1.09 -output_ts_offset 
-60ms" "-c copy -t 0.4"
+
 # This tests writing the MS-compatibility modes V_MS/VFW/FOURCC and A_MS/ACM.
 # It furthermore tests writing the Cues at the front if the cues_to_front
 # option is set and more than enough space has been reserved in advance.
diff --git a/tests/ref/fate/matroska-avoid-negative-ts 
b/tests/ref/fate/matroska-avoid-negative-ts
new file mode 100644
index 00..a687c8f63c
--- /dev/null
+++ b/tests/ref/fate/matroska-avoid-negative-ts
@@ -0,0 +1,42 @@
+3349536550047c5c553215003ba2acb7 
*tests/data/fate/matroska-avoid-negative-ts.matroska
+973070 tests/data/fate/matroska-avoid-negative-ts.matroska
+#extradata 0:   22, 0x2885037c
+#tb 0: 1/1000
+#media_type 0: video
+#codec_id 0: mpeg2video
+#dimensions 0: 352x288
+#sar 0: 12/11
+#tb 1: 1/1000
+#media_type 1: audio
+#codec_id 1: mp3
+#sample_rate 1: 44100
+#channel_layout 1: 4
+#channel_layout_name 1: mono
+0,-37, 24,   40, 9156, 0xe5bd034a, S=1,   40
+1,  0,  0,   26,  417, 0x7198c15e
+0,  3,  3,   40, 1740, 0x29ac4480, F=0x0
+0, 24,123,   40, 3672, 0x98652013, F=0x0
+1, 26, 26,   26,  417, 0x3c67c32d
+1, 52, 52,   26,  417, 0x8c24b1ca
+1, 78, 78,   26,  417, 0x6ee576b7
+0, 83, 83,   40, 2532, 0xa2c42769, F=0x0
+1,104,104,   26,  417, 0x407603db
+0,123,203,   40, 1728, 0xae823d3b, F=0x0
+1,130,130,   26,  417, 0xcf2804d2
+1,156,156,   26,  417, 0xcf2804d2
+0,163,163,   40, 1028, 0x286ac52a, F=0x0
+1,182,182,   26,  417, 0xcf2804d2
+0,203,283,   40, 1916, 0xd378899e, F=0x0
+1,208,208,   26,  417, 0xcf2804d2
+1,235,235,   26,  417, 0xcf2804d2
+0,243,243,   40, 1168, 0x424e12cf, F=0x0
+1,261,261,   26,  417, 0xcf2804d2
+0,283,363,   40, 1660, 0x5cec156c, F=0x0
+1,287,287,   26,  417, 0xcf2804d2
+1,313,313,   26,  417, 0xef163d04
+0,323,323,   40, 1004, 0xac0dce29, F=0x0
+1,339,339,   26,  417, 0x2a009b3a
+0,363,443,   40, 3008, 0x0fc798bf, F=0x0
+1,365,365,   26,  417, 0xbedccb9d
+1,365,365,   26,  417, 0x2214be3f
+1,391,391,   26,  417, 0x8953b878
-- 
2.32.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

[FFmpeg-devel] [PATCH v2 3/6] avformat/avformat: Add AVFMT_AVOID_NEG_TS_DISABLED

2022-01-19 Thread Andreas Rheinhardt
And also don't use explicit constants in the movenc test.

Signed-off-by: Andreas Rheinhardt 
---
 libavformat/avformat.h  | 1 +
 libavformat/mux.c   | 2 +-
 libavformat/options_table.h | 2 +-
 libavformat/tests/movenc.c  | 4 ++--
 libavformat/webm_chunk.c| 2 +-
 5 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 6ce367e854..cd253fb28e 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1533,6 +1533,7 @@ typedef struct AVFormatContext {
  */
 int avoid_negative_ts;
 #define AVFMT_AVOID_NEG_TS_AUTO -1 ///< Enabled when required by 
target format
+#define AVFMT_AVOID_NEG_TS_DISABLED  0 ///< Do not shift timestamps 
even when they are negative.
 #define AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE 1 ///< Shift timestamps so they 
are non negative
 #define AVFMT_AVOID_NEG_TS_MAKE_ZERO 2 ///< Shift timestamps so that 
they start at 0
 
diff --git a/libavformat/mux.c b/libavformat/mux.c
index e34fd88f05..a1917878a5 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -421,7 +421,7 @@ static int init_pts(AVFormatContext *s)
 if (s->avoid_negative_ts < 0) {
 av_assert2(s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO);
 if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) {
-s->avoid_negative_ts = 0;
+s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_DISABLED;
 } else
 s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE;
 }
diff --git a/libavformat/options_table.h b/libavformat/options_table.h
index 62c5bb40a3..86d836cfeb 100644
--- a/libavformat/options_table.h
+++ b/libavformat/options_table.h
@@ -95,7 +95,7 @@ static const AVOption avformat_options[] = {
 {"max_ts_probe", "maximum number of packets to read while waiting for the 
first timestamp", OFFSET(max_ts_probe), AV_OPT_TYPE_INT, { .i64 = 50 }, 0, 
INT_MAX, D },
 {"avoid_negative_ts", "shift timestamps so they start at 0", 
OFFSET(avoid_negative_ts), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, E, 
"avoid_negative_ts"},
 {"auto",  "enabled when required by target format",0, 
AV_OPT_TYPE_CONST, {.i64 = AVFMT_AVOID_NEG_TS_AUTO },  INT_MIN, 
INT_MAX, E, "avoid_negative_ts"},
-{"disabled",  "do not change timestamps",  0, 
AV_OPT_TYPE_CONST, {.i64 = 0 },INT_MIN, 
INT_MAX, E, "avoid_negative_ts"},
+{"disabled",  "do not change timestamps",  0, 
AV_OPT_TYPE_CONST, {.i64 = AVFMT_AVOID_NEG_TS_DISABLED },  INT_MIN, 
INT_MAX, E, "avoid_negative_ts"},
 {"make_non_negative", "shift timestamps so they are non negative", 0, 
AV_OPT_TYPE_CONST, {.i64 = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE }, INT_MIN, 
INT_MAX, E, "avoid_negative_ts"},
 {"make_zero", "shift timestamps so they start at 0",   0, 
AV_OPT_TYPE_CONST, {.i64 = AVFMT_AVOID_NEG_TS_MAKE_ZERO }, INT_MIN, 
INT_MAX, E, "avoid_negative_ts"},
 {"dump_separator", "set information dump field separator", 
OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str = ", "}, 0, 0, D|E},
diff --git a/libavformat/tests/movenc.c b/libavformat/tests/movenc.c
index 2af72f11c7..ddcb053bf2 100644
--- a/libavformat/tests/movenc.c
+++ b/libavformat/tests/movenc.c
@@ -455,7 +455,7 @@ int main(int argc, char **argv)
 init_count_warnings();
 init_out("empty-moov-no-elst-no-adjust");
 av_dict_set(&opts, "movflags", "frag_keyframe+empty_moov", 0);
-av_dict_set(&opts, "avoid_negative_ts", "0", 0);
+av_dict_set(&opts, "avoid_negative_ts", "disabled", 0);
 init(1, 0);
 mux_gops(2);
 finish();
@@ -578,7 +578,7 @@ int main(int argc, char **argv)
 // one before.
 av_dict_set(&opts, "movflags", "frag_custom+empty_moov+dash+frag_discont", 
0);
 av_dict_set(&opts, "fragment_index", "2", 0);
-av_dict_set(&opts, "avoid_negative_ts", "0", 0);
+av_dict_set(&opts, "avoid_negative_ts", "disabled", 0);
 av_dict_set(&opts, "use_editlist", "0", 0);
 init(0, 0);
 skip_gops(1);
diff --git a/libavformat/webm_chunk.c b/libavformat/webm_chunk.c
index 24390e8e74..9348e6680a 100644
--- a/libavformat/webm_chunk.c
+++ b/libavformat/webm_chunk.c
@@ -127,7 +127,7 @@ fail:
 s->avoid_negative_ts  = oc->avoid_negative_ts;
 ffformatcontext(s)->avoid_negative_ts_use_pts =
 ffformatcontext(oc)->avoid_negative_ts_use_pts;
-oc->avoid_negative_ts = 0;
+oc->avoid_negative_ts = AVFMT_AVOID_NEG_TS_DISABLED;
 
 return 0;
 }
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 4/6] avformat/mux: Preserve sync even if later packet has negative ts

2022-01-19 Thread Andreas Rheinhardt
write_packet() has code to shift the packets timestamps
to make them nonnegative or even make them start at ts zero;
this code inspects every packet that is written and if a packet
with negative timestamp (whether this is dts or pts depends upon
another flag; basically: Matroska uses pts, everyone else dts)
is encountered, this is offset to make the timestamp zero.
All further packets will be offset accordingly (with the offset
converted according to the streams' timebases).

This is based around an assumption, namely that the timestamps
are indeed non-decreasing, so that the first packet with negative
timestamps is the first packet with timestamps. This assumption
is often fulfilled given that the default interleavement function
by default interleaves per dts; yet there are scenarios in which
it may not be fulfilled:
a) av_write_frame() instead of av_interleaved_write_frame() is used.
b) The audio_preload option is used.
c) When the timestamps that are made nonnegative/zero are pts
(i.e. with Matroska), because the packet with the smallest dts
is not necessarily the packet with the smallest pts.
d) Possibly with custom interleavement functions.
In these cases the relative sync of the first few packet(s) is offset
relative to the later packets. This contradicts the documentation
("When shifting is enabled, all output timestamps are shifted by
the same amount").

Therefore this commit changes this: As soon as the first packet
with valid timestamps is output, it is checked and recorded whether
the timestamps need to be shifted. Further packets are no longer
checked for needing to be offset; instead they are simply offset.
In the cases above this leads to packets with negative timestamps
(and the appropriate warnings) instead of desync. This will mostly
be fixed in the next commit.

This commit also factors handling the avoid_negative_ts stuff out
of write_packet() in order to be able to return immediately.

Tickets #4536 and #5784 as well as the matroska-avoid-negative-ts-test
are examples of c); as has been said, some timestamps are now negative,
yet the ref file update does not show it because ffmpeg.c sanitizes
the timestamps (-copyts disables it; ffprobe and mkvinfo also show
the original timestamps).

Signed-off-by: Andreas Rheinhardt 
---
 libavformat/internal.h|  23 +++--
 libavformat/mux.c | 111 +-
 libavformat/options.c |   1 -
 tests/fate/matroska.mak   |   4 +-
 tests/ref/fate/matroska-avoid-negative-ts |   6 +-
 5 files changed, 81 insertions(+), 64 deletions(-)

diff --git a/libavformat/internal.h b/libavformat/internal.h
index bffb8e66ff..f24c68703f 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -82,6 +82,17 @@ typedef struct FFFormatContext {
  */
 int nb_interleaved_streams;
 
+/**
+ * Whether the timestamp shift offset has already been determined.
+ * -1: disabled, 0: not yet determined, 1: determined.
+ */
+enum {
+AVOID_NEGATIVE_TS_DISABLED = -1,
+AVOID_NEGATIVE_TS_UNKNOWN  = 0,
+AVOID_NEGATIVE_TS_KNOWN= 1,
+} avoid_negative_ts_status;
+#define AVOID_NEGATIVE_TS_ENABLED(status) ((status) >= 0)
+
 /**
  * The interleavement function in use. Always set for muxers.
  */
@@ -135,18 +146,6 @@ typedef struct FFFormatContext {
  */
 int raw_packet_buffer_size;
 
-/**
- * Offset to remap timestamps to be non-negative.
- * Expressed in timebase units.
- * @see AVStream.mux_ts_offset
- */
-int64_t offset;
-
-/**
- * Timebase for the timestamp offset.
- */
-AVRational offset_timebase;
-
 #if FF_API_COMPUTE_PKT_FIELDS2
 int missing_ts_warning;
 #endif
diff --git a/libavformat/mux.c b/libavformat/mux.c
index a1917878a5..0810b674a7 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -388,6 +388,8 @@ fail:
 
 static int init_pts(AVFormatContext *s)
 {
+FFFormatContext *const si = ffformatcontext(s);
+
 /* init PTS generation */
 for (unsigned i = 0; i < s->nb_streams; i++) {
 AVStream *const st = s->streams[i];
@@ -418,13 +420,16 @@ static int init_pts(AVFormatContext *s)
 }
 }
 
+si->avoid_negative_ts_status = AVOID_NEGATIVE_TS_UNKNOWN;
 if (s->avoid_negative_ts < 0) {
 av_assert2(s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO);
 if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) {
 s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_DISABLED;
+si->avoid_negative_ts_status = AVOID_NEGATIVE_TS_DISABLED;
 } else
 s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE;
-}
+} else if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_DISABLED)
+si->avoid_negative_ts_status = AVOID_NEGATIVE_TS_DISABLED;
 
 return 0;
 }
@@ -638,6 +643,64 @@ static void guess_pkt_duration(AVFormatContext *s, 
AVStream *st, AVPacket *pkt)
 }
 }
 
+static v

[FFmpeg-devel] [PATCH v2 5/6] avformat/mux: Peek into the muxing queue for avoid_negative_ts

2022-01-19 Thread Andreas Rheinhardt
Peeking into the muxing queue can improve the estimate of
the lowest timestamp needed for avoid_negative_ts in case
the lowest timestamp is in a packet other than the first packet
to be muxed.
This fixes tickets #4536 and #5784 as well as the output from
the matroska-avoid-negative-ts FATE-test.

Signed-off-by: Andreas Rheinhardt 
---
 libavformat/avformat.h|  2 +-
 libavformat/mux.c | 21 +++--
 tests/fate/matroska.mak   |  2 --
 tests/ref/fate/matroska-avoid-negative-ts |  2 +-
 4 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index cd253fb28e..b4b8075ae6 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1527,7 +1527,7 @@ typedef struct AVFormatContext {
 /**
  * Avoid negative timestamps during muxing.
  * Any value of the AVFMT_AVOID_NEG_TS_* constants.
- * Note, this only works when using av_interleaved_write_frame. 
(interleave_packet_per_dts is in use)
+ * Note, this works better when using av_interleaved_write_frame().
  * - muxing: Set by user
  * - demuxing: unused
  */
diff --git a/libavformat/mux.c b/libavformat/mux.c
index 0810b674a7..53eb56f0af 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -655,16 +655,33 @@ static void handle_avoid_negative_ts(FFFormatContext *si, 
FFStream *sti,
 if (si->avoid_negative_ts_status == AVOID_NEGATIVE_TS_UNKNOWN) {
 int use_pts = si->avoid_negative_ts_use_pts;
 int64_t ts = use_pts ? pkt->pts : pkt->dts;
+AVRational tb = sti->pub.time_base;
 
 if (ts == AV_NOPTS_VALUE)
 return;
+
+/* Peek into the muxing queue to improve our estimate
+ * of the lowest timestamp if av_interleaved_write_frame() is used. */
+for (const PacketListEntry *pktl = si->packet_buffer.head;
+ pktl; pktl = pktl->next) {
+AVRational cmp_tb = s->streams[pktl->pkt.stream_index]->time_base;
+int64_t cmp_ts = use_pts ? pktl->pkt.pts : pktl->pkt.dts;
+if (cmp_ts == AV_NOPTS_VALUE)
+continue;
+if (s->output_ts_offset)
+cmp_ts += av_rescale_q(s->output_ts_offset, AV_TIME_BASE_Q, 
cmp_tb);
+if (av_compare_ts(cmp_ts, cmp_tb, ts, tb) < 0) {
+ts = cmp_ts;
+tb = cmp_tb;
+}
+}
+
 if (ts < 0 ||
 ts > 0 && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
 for (unsigned i = 0; i < s->nb_streams; i++) {
 AVStream *const st2  = s->streams[i];
 FFStream *const sti2 = ffstream(st2);
-sti2->mux_ts_offset = av_rescale_q_rnd(-ts,
-   sti->pub.time_base,
+sti2->mux_ts_offset = av_rescale_q_rnd(-ts, tb,
st2->time_base,
AV_ROUND_UP);
 }
diff --git a/tests/fate/matroska.mak b/tests/fate/matroska.mak
index da1fdbd5ea..784b55f6e0 100644
--- a/tests/fate/matroska.mak
+++ b/tests/fate/matroska.mak
@@ -94,8 +94,6 @@ fate-matroska-dovi-write-config7: CMD = transcode mov 
$(TARGET_SAMPLES)/mov/dovi
 # the first packet (with the overall lowest dts) is a video packet,
 # whereas an audio packet to be muxed later has the overall lowest pts
 # which happens to be negative and therefore needs to be shifted.
-# This is currently buggy (the timestamps are not shifted properly:
-# the first audio packet has negative pts).
 # (-ss 1.09 ensures that a video frame has the lowest dts of all packets;
 # yet there is an audio packet with the overall lowest pts. output_ts_offset
 # makes the pts of the audio packet, but not the leading video packet negative
diff --git a/tests/ref/fate/matroska-avoid-negative-ts 
b/tests/ref/fate/matroska-avoid-negative-ts
index 1b9b2f2786..02790a3985 100644
--- a/tests/ref/fate/matroska-avoid-negative-ts
+++ b/tests/ref/fate/matroska-avoid-negative-ts
@@ -1,4 +1,4 @@
-90cf5a330659140d47ec11208f525908 
*tests/data/fate/matroska-avoid-negative-ts.matroska
+804842437b2be0a1604ce33c6b08c800 
*tests/data/fate/matroska-avoid-negative-ts.matroska
 973070 tests/data/fate/matroska-avoid-negative-ts.matroska
 #extradata 0:   22, 0x2885037c
 #tb 0: 1/1000
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 6/6] avformat/hls: Remove redundant cast

2022-01-19 Thread Andreas Rheinhardt
Signed-off-by: Andreas Rheinhardt 
---
 libavformat/hls.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/hls.c b/libavformat/hls.c
index 8c526f748f..4568e72cb2 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -2024,7 +2024,7 @@ static int hls_read_header(AVFormatContext *s)
 if (seg && seg->key_type == KEY_SAMPLE_AES && pls->is_id3_timestamped 
&&
 pls->audio_setup_info.codec_id != AV_CODEC_ID_NONE) {
 void *iter = NULL;
-while ((in_fmt = (const AVInputFormat *)av_demuxer_iterate(&iter)))
+while ((in_fmt = av_demuxer_iterate(&iter)))
 if (in_fmt->raw_codec_id == pls->audio_setup_info.codec_id)
 break;
 } else {
-- 
2.32.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 001/289 v6] Add a new channel layout API

2022-01-19 Thread James Almer




On 1/19/2022 5:51 PM, Marton Balint wrote:



On Tue, 18 Jan 2022, James Almer wrote:


From: Anton Khirnov 

The new API is more extensible and allows for custom layouts.
More accurate information is exported, eg for decoders that do not
set a channel layout, lavc will not make one up for them.

Deprecate the old API working with just uint64_t bitmasks.

Expanded and completed by Vittorio Giovara 
and James Almer .
Signed-off-by: Vittorio Giovara 
Signed-off-by: James Almer 
---
Changes since last version:

*av_channel_layout_from_string() and av_channel_layout_describe() now 
support

a "designation@name" syntax, effectively making both functions reciprocal
when there are custom names in some or all channels.
It's the syntax suggested by Marton and is both extensible if required 
and

not too ulgy in human readable output if the string is printed verbatim.

*av_channel_layout_index_from_string() and
av_channel_layout_channel_from_string() also support this syntax now.


I have two suggestions. None of them is actually blocking, but since 
they concern public syntax and API it might be better to decide now.


av_channel_layout_index_from_string() without "@" in the string matches 
both builtin names (designations) and custom names. I suggest for it to 
only match builtin names. If a user wants to match by custom name, 
"@name" may be specified without a designation. This keeps the two 
namespaces separate.


Ok, look into implementing this.



av_channel_layout_channel_from_string() is an API which is not used in 
the codebase. I am not enterely sure about its purpose, so maybe it 
should be removed for now, and only added later, if some code actually 
needs it.


Since you can set custom names and query them without the designation, 
it can be useful as a shortcut for "idx = 
av_channel_layout_index_from_string(str) && 
av_channel_layout_channel_from_index(idx)".

If there were no custom names then yeah, there would be no point to it.



Thanks,
Marton
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 001/289 v6] Add a new channel layout API

2022-01-19 Thread James Almer




On 1/19/2022 3:07 PM, Andreas Rheinhardt wrote:

James Almer:

From: Anton Khirnov 

The new API is more extensible and allows for custom layouts.
More accurate information is exported, eg for decoders that do not
set a channel layout, lavc will not make one up for them.

Deprecate the old API working with just uint64_t bitmasks.

Expanded and completed by Vittorio Giovara 
and James Almer .
Signed-off-by: Vittorio Giovara 
Signed-off-by: James Almer 
---
Changes since last version:

*av_channel_layout_from_string() and av_channel_layout_describe() now support
  a "designation@name" syntax, effectively making both functions reciprocal
  when there are custom names in some or all channels.
  It's the syntax suggested by Marton and is both extensible if required and
  not too ulgy in human readable output if the string is printed verbatim.

*av_channel_layout_index_from_string() and
  av_channel_layout_channel_from_string() also support this syntax now.

I plan to push this version soon. Any extension to the syntax supported by these
helpers can be written by whoever needs it.


You forgot the examples and the tools; and ffplay. And do you really


Ported ffplay. Will port the rest later.


intend for the deprecation warnings in ffmpeg_opt.c to stay?


Ok, I'll silence them.



- Andreas
___
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 v2 00/26] Subtitle Filtering 2022

2022-01-19 Thread ffmpegagent


Subtitle Filtering 2022
===

This is a substantial update to the earlier subtitle filtering patch series.
A primary goal has been to address others' concerns as much as possible on
one side and to provide more clarity and control over the way things are
working. Clarity is is specifically important to allow for a better
understanding of the need for a subtitle start pts value that can be
different from the frame's pts value. This is done by refactoring the
subtitle timing fields in AVFrame, adding a frame field to indicate repeated
subtitle frames, and finally the full removal of the heartbeat
functionality, replaced by a new 'subfeed' filter that provides different
modes for arbitrating subtitle frames in a filter graph. Finally, each
subtitle filter's documentation has been amended by a section describing the
filter's timeline behavior (in v3 update).

The update also includes major improvements to graphicsub2text and lots of
other details.

Versioning is restarting at v1 due to the new submission procedure.


Changes in v2
=

 * added .gitattributes file to enforce binary diffs for the test refs that
   cannot be applied when being sent via e-mail
 * perform filter graph re-init due to subtitle "frame size" change only
   when the size was unknown before and not set via -canvas_size
 * overlaytextsubs: Make sure to request frames on the subtitle input
 * avfilter/splitcc: Start parsing cc data on key frames only
 * avcodec/webvttenc: Don't encode ass drawing codes and empty lines
 * stripstyles: fix mem leak
 * gs2t: improve color detection
 * gs2t: empty frames must not be skipped
 * subfeed: fix name
 * textmod: preserve margins
 * added .gitattributes file to enforce binary diffs for the test refs that
   cannot be applied when being sent via e-mail
 * perform filter graph re-init due to subtitle "frame size" change only
   when the size was unknown before and not set via -canvas_size
 * avcodec/dvbsubdec: Fix conditions for fallback to default resolution
 * Made changes suggested by Andreas
 * Fixed failing command line reported by Michael

Changes from previous version v24:


AVFrame
===

 * Removed sub_start_time The start time is now added to the subtitle
   start_pts during decoding The sub_end_time field is adjusted accordingly
 * Renamed sub_end_time to duration which it is effectively after removing
   the start_time
 * Added a sub-struct 'subtitle_timing' to av frame Contains subtitle_pts
   renamed to 'subtitle_timing.start_pts' and 'subtitle_timing.duration'
 * Change both fields to (fixed) time_base AV_TIMEBASE
 * add repeat_sub field provides a clear indication whether a subtitle frame
   is an actual subtitle event or a repeated subtitle frame in a filter
   graph


Heartbeat Removal
=

 * completely removed the earlier heartbeat implementation
 * filtering arbitration is now implemented in a new filter: 'subfeed'
 * subfeed will be auto-inserted for compatiblity with sub2video command
   lines
 * the new behavior is not exactly identical to the earlier behavior, but it
   basically allows to achieve the same results


New 'subfeed' Filter


 * a versatile filter for solving all kinds of problems with subtile frame
   flow in filter graphs
 * Can be inserted at any position in a graph
 * Auto-inserted for sub2video command lines (in repeat-mode)
 * Allows duration fixup delay input frames with unknown duration and infer
   duration from start of subsequent frame
 * Provides multiple modes of operation:
   * repeat mode (default) Queues input frames Outputs frames at a fixed
 (configurable) rate Either sends a matching input frame (repeatedly) or
 empty frames otherwise
   * scatter mode similar to repeat mode, but splits input frames by
 duration into small segments with same content
   * forward mode No fixed output rate Useful in combination with duration
 fixup or overlap fixup


ffmpeg Tool Changes
===

 * delay subtitle output stream initialization (like for audio and video)
   This is needed for example when a format header depends on having
   received an initial frame to derive certain header values from
 * decoding: set subtitle frame size from decoding context
 * re-init graph when subtitle size changes
 * always insert subscale filter for sub2video command lines (to ensure
   correct scaling)


Subtitle Encoding
=

 * ignore repeated frames for encoding based on repeat_sub field in AVFrame
 * support multi-area encoding for text subtitles Subtitle OCR can create
   multiple areas at different positions. Previously, the texts were always
   squashed into a single area ('subtitle rect'), which was not ideal.
   Multiple text areas are now generally supported:
   * ASS Encoder Changed to use the 'receive_packet' encoding API A single
 frame with multiple text areas will create multiple packets now
   * All other text subtitle encoders A newline is inserte

[FFmpeg-devel] [PATCH v2 01/26] avcodec, avutil: Move enum AVSubtitleType to avutil, add new and deprecate old values

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/avcodec.h | 19 +
 libavutil/Makefile   |  1 +
 libavutil/subfmt.h   | 68 
 libavutil/version.h  |  1 +
 4 files changed, 71 insertions(+), 18 deletions(-)
 create mode 100644 libavutil/subfmt.h

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index ec1a0566a4..fe5a83cf85 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -35,6 +35,7 @@
 #include "libavutil/frame.h"
 #include "libavutil/log.h"
 #include "libavutil/pixfmt.h"
+#include "libavutil/subfmt.h"
 #include "libavutil/rational.h"
 
 #include "codec.h"
@@ -2238,24 +2239,6 @@ typedef struct AVHWAccel {
  * @}
  */
 
-enum AVSubtitleType {
-SUBTITLE_NONE,
-
-SUBTITLE_BITMAP,///< A bitmap, pict will be set
-
-/**
- * Plain text, the text field must be set by the decoder and is
- * authoritative. ass and pict fields may contain approximations.
- */
-SUBTITLE_TEXT,
-
-/**
- * Formatted text, the ass field must be set by the decoder and is
- * authoritative. pict and text fields may contain approximations.
- */
-SUBTITLE_ASS,
-};
-
 #define AV_SUBTITLE_FLAG_FORCED 0x0001
 
 typedef struct AVSubtitleRect {
diff --git a/libavutil/Makefile b/libavutil/Makefile
index d17876df1a..ce644f4d48 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -74,6 +74,7 @@ HEADERS = adler32.h   
  \
   sha512.h  \
   spherical.h   \
   stereo3d.h\
+  subfmt.h  \
   threadmessage.h   \
   time.h\
   timecode.h\
diff --git a/libavutil/subfmt.h b/libavutil/subfmt.h
new file mode 100644
index 00..791b45519f
--- /dev/null
+++ b/libavutil/subfmt.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * 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_SUBFMT_H
+#define AVUTIL_SUBFMT_H
+
+#include "version.h"
+
+enum AVSubtitleType {
+
+/**
+ * Subtitle format unknown.
+ */
+AV_SUBTITLE_FMT_NONE = -1,
+
+/**
+ * Subtitle format unknown.
+ */
+AV_SUBTITLE_FMT_UNKNOWN = 0,
+#if FF_API_OLD_SUBTITLES
+SUBTITLE_NONE = 0,  ///< Deprecated, use AV_SUBTITLE_FMT_NONE 
instead.
+#endif
+
+/**
+ * Bitmap area in AVSubtitleRect.data, pixfmt AV_PIX_FMT_PAL8.
+ */
+AV_SUBTITLE_FMT_BITMAP = 1,
+#if FF_API_OLD_SUBTITLES
+SUBTITLE_BITMAP = 1,///< Deprecated, use AV_SUBTITLE_FMT_BITMAP 
instead.
+#endif
+
+/**
+ * Plain text in AVSubtitleRect.text.
+ */
+AV_SUBTITLE_FMT_TEXT = 2,
+#if FF_API_OLD_SUBTITLES
+SUBTITLE_TEXT = 2,  ///< Deprecated, use AV_SUBTITLE_FMT_TEXT 
instead.
+#endif
+
+/**
+ * Text Formatted as per ASS specification, contained AVSubtitleRect.ass.
+ */
+AV_SUBTITLE_FMT_ASS = 3,
+#if FF_API_OLD_SUBTITLES
+SUBTITLE_ASS = 3,   ///< Deprecated, use AV_SUBTITLE_FMT_ASS 
instead.
+#endif
+
+AV_SUBTITLE_FMT_NB, ///< number of subtitle formats, DO NOT USE 
THIS if you want to link with shared libav* because the number of formats might 
differ between versions.
+};
+
+#endif /* AVUTIL_SUBFMT_H */
diff --git a/libavutil/version.h b/libavutil/version.h
index 953aac9d94..5bf48f6304 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -110,6 +110,7 @@
 #define FF_API_COLORSPACE_NAME  (LIBAVUTIL_VERSION_MAJOR < 58)
 #define FF_API_AV_MALLOCZ_ARRAY (LIBAVUTIL_VERSION_MAJOR < 58)
 #define FF_API_FIFO_PEEK2   (LIBAVUTIL_VERSION_MAJOR < 58)
+#define FF_API_OLD_SUBTITLES(LIBAVUTIL_VERSION_MAJOR < 58)
 
 /**
  * @}
-- 
ffmpeg-codebot

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or ema

[FFmpeg-devel] [PATCH v2 02/26] avutil/frame: Prepare AVFrame for subtitle handling

2022-01-19 Thread ffmpegagent
From: softworkz 

Root commit for adding subtitle filtering capabilities.
In detail:

- Add type (AVMediaType) field to AVFrame
  Replaces previous way of distinction which was based on checking
  width and height to determine whether a frame is audio or video
- Add subtitle fields to AVFrame
- Add new struct AVSubtitleArea, similar to AVSubtitleRect, but
  different allocation logic. Cannot and must not be used
  interchangeably, hence the new struct

Signed-off-by: softworkz 
---
 libavutil/Makefile |   1 +
 libavutil/frame.c  | 211 -
 libavutil/frame.h  |  85 +-
 libavutil/subfmt.c |  45 ++
 libavutil/subfmt.h |  47 ++
 5 files changed, 364 insertions(+), 25 deletions(-)
 create mode 100644 libavutil/subfmt.c

diff --git a/libavutil/Makefile b/libavutil/Makefile
index ce644f4d48..8bc0a14942 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -160,6 +160,7 @@ OBJS = adler32.o
\
slicethread.o\
spherical.o  \
stereo3d.o   \
+   subfmt.o \
threadmessage.o  \
time.o   \
timecode.o   \
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 8997c85e35..2b95830b6f 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -26,6 +26,7 @@
 #include "imgutils.h"
 #include "mem.h"
 #include "samplefmt.h"
+#include "subfmt.h"
 #include "hwcontext.h"
 
 #define CHECK_CHANNELS_CONSISTENCY(frame) \
@@ -50,6 +51,9 @@ const char *av_get_colorspace_name(enum AVColorSpace val)
 return name[val];
 }
 #endif
+
+static int frame_copy_subtitles(AVFrame *dst, const AVFrame *src, int 
copy_data);
+
 static void get_frame_defaults(AVFrame *frame)
 {
 memset(frame, 0, sizeof(*frame));
@@ -70,7 +74,12 @@ static void get_frame_defaults(AVFrame *frame)
 frame->colorspace  = AVCOL_SPC_UNSPECIFIED;
 frame->color_range = AVCOL_RANGE_UNSPECIFIED;
 frame->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
-frame->flags   = 0;
+frame->num_subtitle_areas  = 0;
+frame->subtitle_areas  = NULL;
+frame->subtitle_header = NULL;
+frame->repeat_sub  = 0;
+frame->subtitle_timing.start_pts = 0;
+frame->subtitle_timing.duration  = 0;
 }
 
 static void free_side_data(AVFrameSideData **ptr_sd)
@@ -240,23 +249,55 @@ static int get_audio_buffer(AVFrame *frame, int align)
 
 }
 
+static int get_subtitle_buffer(AVFrame *frame)
+{
+// Buffers in AVFrame->buf[] are not used in case of subtitle frames.
+// To accomodate with existing code, checking ->buf[0] to determine
+// whether a frame is ref-counted or has data, we're adding a 1-byte
+// buffer here, which marks the subtitle frame to contain data.
+frame->buf[0] = av_buffer_alloc(1);
+if (!frame->buf[0]) {
+av_frame_unref(frame);
+return AVERROR(ENOMEM);
+}
+
+frame->extended_data = frame->data;
+
+return 0;
+}
+
 int av_frame_get_buffer(AVFrame *frame, int align)
+{
+if (frame->width > 0 && frame->height > 0)
+frame->type = AVMEDIA_TYPE_VIDEO;
+else if (frame->nb_samples > 0 && (frame->channel_layout || 
frame->channels > 0))
+frame->type = AVMEDIA_TYPE_AUDIO;
+
+return av_frame_get_buffer2(frame, align);
+}
+
+int av_frame_get_buffer2(AVFrame *frame, int align)
 {
 if (frame->format < 0)
 return AVERROR(EINVAL);
 
-if (frame->width > 0 && frame->height > 0)
+switch(frame->type) {
+case AVMEDIA_TYPE_VIDEO:
 return get_video_buffer(frame, align);
-else if (frame->nb_samples > 0 && (frame->channel_layout || 
frame->channels > 0))
+case AVMEDIA_TYPE_AUDIO:
 return get_audio_buffer(frame, align);
-
-return AVERROR(EINVAL);
+case AVMEDIA_TYPE_SUBTITLE:
+return get_subtitle_buffer(frame);
+default:
+return AVERROR(EINVAL);
+}
 }
 
 static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy)
 {
 int ret, i;
 
+dst->type   = src->type;
 dst->key_frame  = src->key_frame;
 dst->pict_type  = src->pict_type;
 dst->sample_aspect_ratio= src->sample_aspect_ratio;
@@ -288,6 +329,12 @@ static int frame_copy_props(AVFrame *dst, const AVFrame 
*src, int force_copy)
 dst->colorspace = src->colorspace;
 dst->color_range= src->color_range;
 dst->chroma_location= src->chroma_location;
+dst->repeat_sub = src->repeat_sub;
+dst->subtitle_timing.start_pts = src->subtitle_timing.start_pts;
+  

[FFmpeg-devel] [PATCH v2 03/26] avcodec/subtitles: Introduce new frame-based subtitle decoding API

2022-01-19 Thread ffmpegagent
From: softworkz 

- Modify avcodec_send_packet() to support subtitles via the regular
  frame based decoding API
- Add decode_subtitle_shim() which takes subtitle frames,
  and serves as a compatibility shim to the legacy subtitle decoding
  API until all subtitle decoders are migrated to the frame-based API
- Add additional methods for conversion between old and new API

Signed-off-by: softworkz 
---
 libavcodec/avcodec.h|   8 +-
 libavcodec/codec_desc.c |  11 +++
 libavcodec/codec_desc.h |   8 ++
 libavcodec/decode.c |  60 +++--
 libavcodec/internal.h   |  16 
 libavcodec/utils.c  | 184 
 6 files changed, 278 insertions(+), 9 deletions(-)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index fe5a83cf85..9d59f6e840 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1675,7 +1675,7 @@ typedef struct AVCodecContext {
 
 /**
  * Header containing style information for text subtitles.
- * For SUBTITLE_ASS subtitle type, it should contain the whole ASS
+ * For AV_SUBTITLE_FMT_ASS subtitle type, it should contain the whole ASS
  * [Script Info] and [V4+ Styles] section, plus the [Events] line and
  * the Format line following. It shouldn't include any Dialogue line.
  * - encoding: Set/allocated/freed by user (before avcodec_open2())
@@ -2415,7 +2415,10 @@ int avcodec_close(AVCodecContext *avctx);
  * Free all allocated data in the given subtitle struct.
  *
  * @param sub AVSubtitle to free.
+ *
+ * @deprecated Use the regular frame based encode and decode APIs instead.
  */
+attribute_deprecated
 void avsubtitle_free(AVSubtitle *sub);
 
 /**
@@ -2508,7 +2511,10 @@ enum AVChromaLocation avcodec_chroma_pos_to_enum(int 
xpos, int ypos);
  * must be freed with avsubtitle_free if *got_sub_ptr is set.
  * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, 
otherwise, it is nonzero.
  * @param[in] avpkt The input AVPacket containing the input buffer.
+ *
+ * @deprecated Use the new decode API (avcodec_send_packet, 
avcodec_receive_frame) instead.
  */
+attribute_deprecated
 int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
 int *got_sub_ptr,
 AVPacket *avpkt);
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 0974ee03de..e48e4532ba 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -3548,3 +3548,14 @@ enum AVMediaType avcodec_get_type(enum AVCodecID 
codec_id)
 const AVCodecDescriptor *desc = avcodec_descriptor_get(codec_id);
 return desc ? desc->type : AVMEDIA_TYPE_UNKNOWN;
 }
+
+enum AVSubtitleType avcodec_descriptor_get_subtitle_format(const 
AVCodecDescriptor *codec_descriptor)
+{
+if(codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB)
+return AV_SUBTITLE_FMT_BITMAP;
+
+if(codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB)
+return AV_SUBTITLE_FMT_ASS;
+
+return AV_SUBTITLE_FMT_UNKNOWN;
+}
diff --git a/libavcodec/codec_desc.h b/libavcodec/codec_desc.h
index 126b52df47..ba68d24e0e 100644
--- a/libavcodec/codec_desc.h
+++ b/libavcodec/codec_desc.h
@@ -121,6 +121,14 @@ const AVCodecDescriptor *avcodec_descriptor_next(const 
AVCodecDescriptor *prev);
  */
 const AVCodecDescriptor *avcodec_descriptor_get_by_name(const char *name);
 
+/**
+ * Return subtitle format from a codec descriptor
+ *
+ * @param codec_descriptor codec descriptor
+ * @return the subtitle type (e.g. bitmap, text)
+ */
+enum AVSubtitleType avcodec_descriptor_get_subtitle_format(const 
AVCodecDescriptor *codec_descriptor);
+
 /**
  * @}
  */
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 0912f86a14..e3cf1cfa3d 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -576,6 +576,39 @@ static int decode_receive_frame_internal(AVCodecContext 
*avctx, AVFrame *frame)
 return ret;
 }
 
+static int decode_subtitle2_priv(AVCodecContext *avctx, AVSubtitle *sub,
+ int *got_sub_ptr, AVPacket *avpkt);
+
+static int decode_subtitle_shim(AVCodecContext *avctx, AVFrame *frame, 
AVPacket *avpkt)
+{
+int ret, got_sub_ptr = 0;
+AVSubtitle subtitle = { 0 };
+
+if (frame->buf[0])
+return AVERROR(EAGAIN);
+
+av_frame_unref(frame);
+
+ret = decode_subtitle2_priv(avctx, &subtitle, &got_sub_ptr, avpkt);
+
+if (ret >= 0 && got_sub_ptr) {
+frame->type = AVMEDIA_TYPE_SUBTITLE;
+frame->format = subtitle.format;
+ret = av_frame_get_buffer2(frame, 0);
+
+if (ret >= 0)
+ret = ff_frame_put_subtitle(frame, &subtitle);
+
+frame->width = avctx->width;
+frame->height = avctx->height;
+frame->pkt_dts = avpkt->dts;
+}
+
+avsubtitle_free(&subtitle);
+
+return ret;
+}
+
 int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const 
AVPacket *avpkt)
 {
 AVCodecInternal *avci = avctx->internal;
@@ -59

[FFmpeg-devel] [PATCH v2 04/26] avfilter/subtitles: Update vf_subtitles to use new decoding api

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_subtitles.c | 56 +-
 1 file changed, 43 insertions(+), 13 deletions(-)

diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c
index 3fc4eeb63d..25e217e845 100644
--- a/libavfilter/vf_subtitles.c
+++ b/libavfilter/vf_subtitles.c
@@ -35,14 +35,12 @@
 # include "libavformat/avformat.h"
 #endif
 #include "libavutil/avstring.h"
-#include "libavutil/imgutils.h"
 #include "libavutil/opt.h"
 #include "libavutil/parseutils.h"
 #include "drawutils.h"
 #include "avfilter.h"
 #include "internal.h"
 #include "formats.h"
-#include "video.h"
 
 typedef struct AssContext {
 const AVClass *class;
@@ -292,6 +290,29 @@ static int attachment_is_font(AVStream * st)
 return 0;
 }
 
+static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, 
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)
+*got_frame = 1;
+
+return 0;
+}
+
 AVFILTER_DEFINE_CLASS(subtitles);
 
 static av_cold int init_subtitles(AVFilterContext *ctx)
@@ -306,6 +327,7 @@ static av_cold int init_subtitles(AVFilterContext *ctx)
 AVStream *st;
 AVPacket pkt;
 AssContext *ass = ctx->priv;
+enum AVSubtitleType subtitle_format;
 
 /* Init libass */
 ret = init(ctx);
@@ -386,13 +408,17 @@ static av_cold int init_subtitles(AVFilterContext *ctx)
 ret = AVERROR_DECODER_NOT_FOUND;
 goto end;
 }
+
 dec_desc = avcodec_descriptor_get(st->codecpar->codec_id);
-if (dec_desc && !(dec_desc->props & AV_CODEC_PROP_TEXT_SUB)) {
+subtitle_format = avcodec_descriptor_get_subtitle_format(dec_desc);
+
+if (subtitle_format != AV_SUBTITLE_FMT_ASS) {
 av_log(ctx, AV_LOG_ERROR,
-   "Only text based subtitles are currently supported\n");
-ret = AVERROR_PATCHWELCOME;
+   "Only text based subtitles are supported by this filter\n");
+ret = AVERROR_INVALIDDATA;
 goto end;
 }
+
 if (ass->charenc)
 av_dict_set(&codec_opts, "sub_charenc", ass->charenc, 0);
 
@@ -448,27 +474,31 @@ static av_cold int init_subtitles(AVFilterContext *ctx)
   dec_ctx->subtitle_header_size);
 while (av_read_frame(fmt, &pkt) >= 0) {
 int i, got_subtitle;
-AVSubtitle sub = {0};
+AVFrame *sub = av_frame_alloc();
+if (!sub) {
+ret = AVERROR(ENOMEM);
+goto end;
+}
 
 if (pkt.stream_index == sid) {
-ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_subtitle, &pkt);
+ret = decode(dec_ctx, sub, &got_subtitle, &pkt);
 if (ret < 0) {
 av_log(ctx, AV_LOG_WARNING, "Error decoding: %s (ignored)\n",
av_err2str(ret));
 } else if (got_subtitle) {
-const int64_t start_time = av_rescale_q(sub.pts, 
AV_TIME_BASE_Q, av_make_q(1, 1000));
-const int64_t duration   = sub.end_display_time;
-for (i = 0; i < sub.num_rects; i++) {
-char *ass_line = sub.rects[i]->ass;
+const int64_t start_time = 
av_rescale_q(sub->subtitle_timing.start_pts, AV_TIME_BASE_Q, av_make_q(1, 
1000));
+const int64_t duration   = 
av_rescale_q(sub->subtitle_timing.duration, AV_TIME_BASE_Q, av_make_q(1, 1000));
+for (i = 0; i < sub->num_subtitle_areas; i++) {
+char *ass_line = sub->subtitle_areas[i]->ass;
 if (!ass_line)
-break;
+continue;
 ass_process_chunk(ass->track, ass_line, strlen(ass_line),
   start_time, duration);
 }
 }
 }
 av_packet_unref(&pkt);
-avsubtitle_free(&sub);
+av_frame_free(&sub);
 }
 
 end:
-- 
ffmpeg-codebot

___
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 10/26] avfilter/avfilter: Fix hardcoded input index

2022-01-19 Thread ffmpegagent
From: softworkz 

This fix targets (rare) cases where multiple input pads have a
.filter_frame function. ff_request_frame_to_filter needs
to call ff_request_frame with the correct input pad
instead of the hardcoded first one.

Signed-off-by: softworkz 
---
 libavfilter/avfilter.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 75d5e86539..aa9aa71f53 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -463,7 +463,7 @@ static int64_t guess_status_pts(AVFilterContext *ctx, int 
status, AVRational lin
 return AV_NOPTS_VALUE;
 }
 
-static int ff_request_frame_to_filter(AVFilterLink *link)
+static int ff_request_frame_to_filter(AVFilterLink *link, int input_index)
 {
 int ret = -1;
 
@@ -472,8 +472,8 @@ static int ff_request_frame_to_filter(AVFilterLink *link)
 link->frame_blocked_in = 1;
 if (link->srcpad->request_frame)
 ret = link->srcpad->request_frame(link);
-else if (link->src->inputs[0])
-ret = ff_request_frame(link->src->inputs[0]);
+else if (link->src->inputs[input_index])
+ret = ff_request_frame(link->src->inputs[input_index]);
 if (ret < 0) {
 if (ret != AVERROR(EAGAIN) && ret != link->status_in)
 ff_avfilter_link_set_in_status(link, ret, 
guess_status_pts(link->src, ret, link->time_base));
@@ -1172,6 +1172,14 @@ static int forward_status_change(AVFilterContext 
*filter, AVFilterLink *in)
 {
 unsigned out = 0, progress = 0;
 int ret;
+int input_index = 0;
+
+for (int i = 0; i < in->dst->nb_inputs; i++) {
+if (&in->dst->input_pads[i] == in->dstpad) {
+input_index = i;
+break;
+}
+}
 
 av_assert0(!in->status_out);
 if (!filter->nb_outputs) {
@@ -1181,7 +1189,7 @@ static int forward_status_change(AVFilterContext *filter, 
AVFilterLink *in)
 while (!in->status_out) {
 if (!filter->outputs[out]->status_in) {
 progress++;
-ret = ff_request_frame_to_filter(filter->outputs[out]);
+ret = ff_request_frame_to_filter(filter->outputs[out], 
input_index);
 if (ret < 0)
 return ret;
 }
@@ -1218,7 +1226,7 @@ static int ff_filter_activate_default(AVFilterContext 
*filter)
 for (i = 0; i < filter->nb_outputs; i++) {
 if (filter->outputs[i]->frame_wanted_out &&
 !filter->outputs[i]->frame_blocked_in) {
-return ff_request_frame_to_filter(filter->outputs[i]);
+return ff_request_frame_to_filter(filter->outputs[i], 0);
 }
 }
 return FFERROR_NOT_READY;
-- 
ffmpeg-codebot

___
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 06/26] avcodec/subtitles: Replace deprecated enum values

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/ass.h   | 2 +-
 libavcodec/assdec.c| 2 +-
 libavcodec/dvbsubdec.c | 2 +-
 libavcodec/dvdsubdec.c | 2 +-
 libavcodec/dvdsubenc.c | 2 +-
 libavcodec/pgssubdec.c | 2 +-
 libavcodec/xsubdec.c   | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/libavcodec/ass.h b/libavcodec/ass.h
index 8bc13d7ab8..43c5ad651a 100644
--- a/libavcodec/ass.h
+++ b/libavcodec/ass.h
@@ -83,7 +83,7 @@ static inline int avpriv_ass_add_rect(AVSubtitle *sub, const 
char *dialog,
 rects[sub->num_rects]   = av_mallocz(sizeof(*rects[0]));
 if (!rects[sub->num_rects])
 return AVERROR(ENOMEM);
-rects[sub->num_rects]->type = SUBTITLE_ASS;
+rects[sub->num_rects]->type = AV_SUBTITLE_FMT_ASS;
 ass_str = avpriv_ass_get_dialog(readorder, layer, style, speaker, dialog);
 if (!ass_str)
 return AVERROR(ENOMEM);
diff --git a/libavcodec/assdec.c b/libavcodec/assdec.c
index 7802a44e71..fd321e7004 100644
--- a/libavcodec/assdec.c
+++ b/libavcodec/assdec.c
@@ -54,7 +54,7 @@ static int ass_decode_frame(AVCodecContext *avctx, void 
*data, int *got_sub_ptr,
 if (!sub->rects[0])
 return AVERROR(ENOMEM);
 sub->num_rects = 1;
-sub->rects[0]->type = SUBTITLE_ASS;
+sub->rects[0]->type = AV_SUBTITLE_FMT_ASS;
 sub->rects[0]->ass  = av_strdup(avpkt->data);
 if (!sub->rects[0]->ass)
 return AVERROR(ENOMEM);
diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c
index bc741a1de6..0d64c6e71c 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -795,7 +795,7 @@ static int save_subtitle_set(AVCodecContext *avctx, 
AVSubtitle *sub, int *got_ou
 rect->w = region->width;
 rect->h = region->height;
 rect->nb_colors = (1 << region->depth);
-rect->type  = SUBTITLE_BITMAP;
+rect->type  = AV_SUBTITLE_FMT_BITMAP;
 rect->linesize[0] = region->width;
 
 clut = get_clut(ctx, region->clut);
diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c
index 52259f0730..b39b3d1838 100644
--- a/libavcodec/dvdsubdec.c
+++ b/libavcodec/dvdsubdec.c
@@ -406,7 +406,7 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, 
AVSubtitle *sub_header,
 sub_header->rects[0]->y = y1;
 sub_header->rects[0]->w = w;
 sub_header->rects[0]->h = h;
-sub_header->rects[0]->type = SUBTITLE_BITMAP;
+sub_header->rects[0]->type = AV_SUBTITLE_FMT_BITMAP;
 sub_header->rects[0]->linesize[0] = w;
 sub_header->rects[0]->flags = is_menu ? 
AV_SUBTITLE_FLAG_FORCED : 0;
 }
diff --git a/libavcodec/dvdsubenc.c b/libavcodec/dvdsubenc.c
index ff4fbed39d..943a7466d9 100644
--- a/libavcodec/dvdsubenc.c
+++ b/libavcodec/dvdsubenc.c
@@ -268,7 +268,7 @@ static int encode_dvd_subtitles(AVCodecContext *avctx,
 if (rects == 0 || !h->rects)
 return AVERROR(EINVAL);
 for (i = 0; i < rects; i++)
-if (h->rects[i]->type != SUBTITLE_BITMAP) {
+if (h->rects[i]->type != AV_SUBTITLE_FMT_BITMAP) {
 av_log(avctx, AV_LOG_ERROR, "Bitmap subtitle required\n");
 return AVERROR(EINVAL);
 }
diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c
index bdd20c914b..22b6616f9b 100644
--- a/libavcodec/pgssubdec.c
+++ b/libavcodec/pgssubdec.c
@@ -535,7 +535,7 @@ static int display_end_segment(AVCodecContext *avctx, void 
*data,
 if (!rect)
 return AVERROR(ENOMEM);
 sub->rects[sub->num_rects++] = rect;
-rect->type = SUBTITLE_BITMAP;
+rect->type = AV_SUBTITLE_FMT_BITMAP;
 
 /* Process bitmap */
 object = find_object(ctx->presentation.objects[i].id, &ctx->objects);
diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c
index 85cd7d1c20..a4be18a1d8 100644
--- a/libavcodec/xsubdec.c
+++ b/libavcodec/xsubdec.c
@@ -107,7 +107,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, 
int *got_sub_ptr,
 sub->num_rects = 1;
 rect->x = x; rect->y = y;
 rect->w = w; rect->h = h;
-rect->type = SUBTITLE_BITMAP;
+rect->type = AV_SUBTITLE_FMT_BITMAP;
 rect->linesize[0] = w;
 rect->data[0] = av_malloc(w * h);
 rect->nb_colors = 4;
-- 
ffmpeg-codebot

___
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 05/26] avcodec, avutil: Move ass helper functions to avutil as avpriv_ and extend ass dialog parsing

2022-01-19 Thread ffmpegagent
From: softworkz 

Also add

- hard_space callback (for upcoming fix)
- extensible callback (for future extension)

Signed-off-by: softworkz 
---
 libavcodec/Makefile   |  56 +++
 libavcodec/ass.h  | 144 ++
 libavcodec/assdec.c   |   2 +-
 libavcodec/assenc.c   |   2 +-
 libavcodec/ccaption_dec.c |  19 +--
 libavcodec/jacosubdec.c   |   2 +-
 libavcodec/libaribb24.c   |   2 +-
 libavcodec/libzvbi-teletextdec.c  |  14 +-
 libavcodec/microdvddec.c  |   7 +-
 libavcodec/movtextdec.c   |   3 +-
 libavcodec/movtextenc.c   |  20 +--
 libavcodec/mpl2dec.c  |   2 +-
 libavcodec/realtextdec.c  |   2 +-
 libavcodec/samidec.c  |   2 +-
 libavcodec/srtdec.c   |   2 +-
 libavcodec/srtenc.c   |  16 +-
 libavcodec/subviewerdec.c |   2 +-
 libavcodec/textdec.c  |   4 +-
 libavcodec/ttmlenc.c  |  15 +-
 libavcodec/webvttdec.c|   2 +-
 libavcodec/webvttenc.c|  16 +-
 libavutil/Makefile|   2 +
 {libavcodec => libavutil}/ass.c   |  91 +--
 libavutil/ass_internal.h  | 135 
 {libavcodec => libavutil}/ass_split.c |  30 ++--
 .../ass_split_internal.h  |  32 ++--
 26 files changed, 355 insertions(+), 269 deletions(-)
 rename {libavcodec => libavutil}/ass.c (65%)
 create mode 100644 libavutil/ass_internal.h
 rename {libavcodec => libavutil}/ass_split.c (94%)
 rename libavcodec/ass_split.h => libavutil/ass_split_internal.h (86%)

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index cfc70a3eaf..80bf8ff2d2 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -215,10 +215,10 @@ OBJS-$(CONFIG_APNG_DECODER)+= png.o pngdec.o 
pngdsp.o
 OBJS-$(CONFIG_APNG_ENCODER)+= png.o pngenc.o
 OBJS-$(CONFIG_ARBC_DECODER)+= arbc.o
 OBJS-$(CONFIG_ARGO_DECODER)+= argo.o
-OBJS-$(CONFIG_SSA_DECODER) += assdec.o ass.o
-OBJS-$(CONFIG_SSA_ENCODER) += assenc.o ass.o
-OBJS-$(CONFIG_ASS_DECODER) += assdec.o ass.o
-OBJS-$(CONFIG_ASS_ENCODER) += assenc.o ass.o
+OBJS-$(CONFIG_SSA_DECODER) += assdec.o
+OBJS-$(CONFIG_SSA_ENCODER) += assenc.o
+OBJS-$(CONFIG_ASS_DECODER) += assdec.o
+OBJS-$(CONFIG_ASS_ENCODER) += assenc.o
 OBJS-$(CONFIG_ASV1_DECODER)+= asvdec.o asv.o mpeg12data.o
 OBJS-$(CONFIG_ASV1_ENCODER)+= asvenc.o asv.o mpeg12data.o
 OBJS-$(CONFIG_ASV2_DECODER)+= asvdec.o asv.o mpeg12data.o
@@ -259,7 +259,7 @@ OBJS-$(CONFIG_BRENDER_PIX_DECODER) += brenderpix.o
 OBJS-$(CONFIG_C93_DECODER) += c93.o
 OBJS-$(CONFIG_CAVS_DECODER)+= cavs.o cavsdec.o cavsdsp.o \
   cavsdata.o
-OBJS-$(CONFIG_CCAPTION_DECODER)+= ccaption_dec.o ass.o
+OBJS-$(CONFIG_CCAPTION_DECODER)+= ccaption_dec.o
 OBJS-$(CONFIG_CDGRAPHICS_DECODER)  += cdgraphics.o
 OBJS-$(CONFIG_CDTOONS_DECODER) += cdtoons.o
 OBJS-$(CONFIG_CDXL_DECODER)+= cdxl.o
@@ -434,7 +434,7 @@ OBJS-$(CONFIG_INTERPLAY_ACM_DECODER)   += interplayacm.o
 OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER)  += dpcm.o
 OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o
 OBJS-$(CONFIG_IPU_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o
-OBJS-$(CONFIG_JACOSUB_DECODER) += jacosubdec.o ass.o
+OBJS-$(CONFIG_JACOSUB_DECODER) += jacosubdec.o
 OBJS-$(CONFIG_JPEG2000_ENCODER)+= j2kenc.o mqcenc.o mqc.o jpeg2000.o \
   jpeg2000dwt.o
 OBJS-$(CONFIG_JPEG2000_DECODER)+= jpeg2000dec.o jpeg2000.o 
jpeg2000dsp.o \
@@ -456,7 +456,7 @@ OBJS-$(CONFIG_MAGICYUV_ENCODER)+= magicyuvenc.o
 OBJS-$(CONFIG_MDEC_DECODER)+= mdec.o mpeg12.o mpeg12data.o
 OBJS-$(CONFIG_METASOUND_DECODER)   += metasound.o metasound_data.o \
   twinvq.o
-OBJS-$(CONFIG_MICRODVD_DECODER)+= microdvddec.o ass.o
+OBJS-$(CONFIG_MICRODVD_DECODER)+= microdvddec.o
 OBJS-$(CONFIG_MIMIC_DECODER)   += mimic.o
 OBJS-$(CONFIG_MJPEG_DECODER)   += mjpegdec.o mjpegdec_common.o
 OBJS-$(CONFIG_MJPEG_QSV_DECODER)   += qsvdec.o
@@ -471,8 +471,8 @@ OBJS-$(CONFIG_MLP_ENCODER) += mlpenc.o mlp.o
 OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o
 OBJS-$(CONFIG_MOBICLIP_DECODER)+= mobiclip.o
 OBJS-$(CONFIG_MOTIONPIXELS_DECODER)+= motionpixels.o
-OBJS-$(CONFIG_MOVTEXT_DECODER) += movtextdec.o ass.o
-OBJS-$(CONFIG_MOVTEXT_ENCOD

[FFmpeg-devel] [PATCH v2 11/26] avfilter/sbuffer: Add sbuffersrc and sbuffersink filters

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 configure|  2 +-
 libavfilter/allfilters.c |  2 ++
 libavfilter/buffersink.c | 54 ++
 libavfilter/buffersink.h |  7 
 libavfilter/buffersrc.c  | 72 
 libavfilter/buffersrc.h  |  1 +
 6 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 1413122d87..7c2931bd50 100755
--- a/configure
+++ b/configure
@@ -7854,7 +7854,7 @@ print_enabled_components(){
 fi
 done
 if [ "$name" = "filter_list" ]; then
-for c in asrc_abuffer vsrc_buffer asink_abuffer vsink_buffer; do
+for c in asrc_abuffer vsrc_buffer ssrc_sbuffer asink_abuffer 
vsink_buffer ssink_sbuffer; do
 printf "&ff_%s,\n" $c >> $TMPH
 done
 fi
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 4325a3e557..8a3bd03924 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -556,8 +556,10 @@ extern const AVFilter ff_avsrc_movie;
  * being the same while having different 'types'). */
 extern  const AVFilter ff_asrc_abuffer;
 extern  const AVFilter ff_vsrc_buffer;
+extern  const AVFilter ff_ssrc_sbuffer;
 extern  const AVFilter ff_asink_abuffer;
 extern  const AVFilter ff_vsink_buffer;
+extern  const AVFilter ff_ssink_sbuffer;
 extern const AVFilter ff_af_afifo;
 extern const AVFilter ff_vf_fifo;
 
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
index c0215669e7..0b268c2fa4 100644
--- a/libavfilter/buffersink.c
+++ b/libavfilter/buffersink.c
@@ -29,6 +29,8 @@
 #include "libavutil/internal.h"
 #include "libavutil/opt.h"
 
+#include "libavcodec/avcodec.h"
+
 #define FF_INTERNAL_FIELDS 1
 #include "framequeue.h"
 
@@ -57,6 +59,10 @@ typedef struct BufferSinkContext {
 int *sample_rates;  ///< list of accepted sample rates
 int sample_rates_size;
 
+/* only used for subtitles */
+enum AVSubtitleType *subtitle_types; ///< list of accepted subtitle 
types, must be terminated with -1
+int subtitle_types_size;
+
 AVFrame *peeked_frame;
 } BufferSinkContext;
 
@@ -305,6 +311,28 @@ static int asink_query_formats(AVFilterContext *ctx)
 return 0;
 }
 
+static int ssink_query_formats(AVFilterContext *ctx)
+{
+BufferSinkContext *buf = ctx->priv;
+AVFilterFormats *formats = NULL;
+unsigned i;
+int ret;
+
+CHECK_LIST_SIZE(subtitle_types)
+if (buf->subtitle_types_size) {
+for (i = 0; i < NB_ITEMS(buf->subtitle_types); i++)
+if ((ret = ff_add_subtitle_type(&formats, buf->subtitle_types[i])) 
< 0)
+return ret;
+if ((ret = ff_set_common_formats(ctx, formats)) < 0)
+return ret;
+} else {
+if ((ret = ff_default_query_formats(ctx)) < 0)
+return ret;
+}
+
+return 0;
+}
+
 #define OFFSET(x) offsetof(BufferSinkContext, x)
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 static const AVOption buffersink_options[] = {
@@ -322,9 +350,16 @@ static const AVOption abuffersink_options[] = {
 { NULL },
 };
 #undef FLAGS
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_SUBTITLE_PARAM
+static const AVOption sbuffersink_options[] = {
+{ "subtitle_types", "set the supported subtitle formats", 
OFFSET(subtitle_types), AV_OPT_TYPE_BINARY, .flags = FLAGS },
+{ NULL },
+};
+#undef FLAGS
 
 AVFILTER_DEFINE_CLASS(buffersink);
 AVFILTER_DEFINE_CLASS(abuffersink);
+AVFILTER_DEFINE_CLASS(sbuffersink);
 
 static const AVFilterPad avfilter_vsink_buffer_inputs[] = {
 {
@@ -363,3 +398,22 @@ const AVFilter ff_asink_abuffer = {
 .outputs   = NULL,
 FILTER_QUERY_FUNC(asink_query_formats),
 };
+
+static const AVFilterPad avfilter_ssink_sbuffer_inputs[] = {
+{
+.name = "default",
+.type = AVMEDIA_TYPE_SUBTITLE,
+},
+};
+
+const AVFilter ff_ssink_sbuffer = {
+.name  = "sbuffersink",
+.description   = NULL_IF_CONFIG_SMALL("Buffer subtitle frames, and make 
them available to the end of the filter graph."),
+.priv_class= &sbuffersink_class,
+.priv_size = sizeof(BufferSinkContext),
+.init  = common_init,
+.activate  = activate,
+FILTER_INPUTS(avfilter_ssink_sbuffer_inputs),
+.outputs   = NULL,
+FILTER_QUERY_FUNC(ssink_query_formats),
+};
diff --git a/libavfilter/buffersink.h b/libavfilter/buffersink.h
index 69ed0f29a8..11905abdc5 100644
--- a/libavfilter/buffersink.h
+++ b/libavfilter/buffersink.h
@@ -129,6 +129,13 @@ typedef struct AVABufferSinkParams {
  */
 attribute_deprecated
 AVABufferSinkParams *av_abuffersink_params_alloc(void);
+
+/**
+ * Deprecated and unused struct to use for initializing an sbuffersink context.
+ */
+typedef struct AVSBufferSinkParams {
+const int *subtitle_type;
+} AVSBufferSinkParams;
 #endif
 
 /**
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
index b0611872f1..d2362999a2 100644
--- a/liba

[FFmpeg-devel] [PATCH v2 07/26] fftools/play, probe: Adjust for subtitle changes

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 fftools/ffplay.c  | 102 +-
 fftools/ffprobe.c |  47 +
 2 files changed, 77 insertions(+), 72 deletions(-)

diff --git a/fftools/ffplay.c b/fftools/ffplay.c
index e7b20be76b..94286eb678 100644
--- a/fftools/ffplay.c
+++ b/fftools/ffplay.c
@@ -152,7 +152,6 @@ typedef struct Clock {
 /* Common struct for handling all types of decoded data and allocated render 
buffers. */
 typedef struct Frame {
 AVFrame *frame;
-AVSubtitle sub;
 int serial;
 double pts;   /* presentation timestamp for the frame */
 double duration;  /* estimated duration of the frame */
@@ -586,7 +585,7 @@ static int decoder_init(Decoder *d, AVCodecContext *avctx, 
PacketQueue *queue, S
 return 0;
 }
 
-static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
+static int decoder_decode_frame(Decoder *d, AVFrame *frame) {
 int ret = AVERROR(EAGAIN);
 
 for (;;) {
@@ -620,6 +619,9 @@ static int decoder_decode_frame(Decoder *d, AVFrame *frame, 
AVSubtitle *sub) {
 }
 }
 break;
+case AVMEDIA_TYPE_SUBTITLE:
+ret = avcodec_receive_frame(d->avctx, frame);
+break;
 }
 if (ret == AVERROR_EOF) {
 d->finished = d->pkt_serial;
@@ -652,25 +654,11 @@ static int decoder_decode_frame(Decoder *d, AVFrame 
*frame, AVSubtitle *sub) {
 av_packet_unref(d->pkt);
 } while (1);
 
-if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
-int got_frame = 0;
-ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, d->pkt);
-if (ret < 0) {
-ret = AVERROR(EAGAIN);
-} else {
-if (got_frame && !d->pkt->data) {
-d->packet_pending = 1;
-}
-ret = got_frame ? 0 : (d->pkt->data ? AVERROR(EAGAIN) : 
AVERROR_EOF);
-}
-av_packet_unref(d->pkt);
+if (avcodec_send_packet(d->avctx, d->pkt) == AVERROR(EAGAIN)) {
+av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet both 
returned EAGAIN, which is an API violation.\n");
+d->packet_pending = 1;
 } else {
-if (avcodec_send_packet(d->avctx, d->pkt) == AVERROR(EAGAIN)) {
-av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet 
both returned EAGAIN, which is an API violation.\n");
-d->packet_pending = 1;
-} else {
-av_packet_unref(d->pkt);
-}
+av_packet_unref(d->pkt);
 }
 }
 }
@@ -683,7 +671,6 @@ static void decoder_destroy(Decoder *d) {
 static void frame_queue_unref_item(Frame *vp)
 {
 av_frame_unref(vp->frame);
-avsubtitle_free(&vp->sub);
 }
 
 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, 
int keep_last)
@@ -981,7 +968,7 @@ static void video_image_display(VideoState *is)
 if (frame_queue_nb_remaining(&is->subpq) > 0) {
 sp = frame_queue_peek(&is->subpq);
 
-if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 
1000)) {
+if (vp->pts >= sp->pts) {
 if (!sp->uploaded) {
 uint8_t* pixels[4];
 int pitch[4];
@@ -993,25 +980,27 @@ static void video_image_display(VideoState *is)
 if (realloc_texture(&is->sub_texture, 
SDL_PIXELFORMAT_ARGB, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
 return;
 
-for (i = 0; i < sp->sub.num_rects; i++) {
-AVSubtitleRect *sub_rect = sp->sub.rects[i];
+for (i = 0; i < sp->frame->num_subtitle_areas; i++) {
+AVSubtitleArea *area = sp->frame->subtitle_areas[i];
+SDL_Rect sdl_rect = { .x = area->x, .y = area->y, .w = 
area->w, .h = area->h };
 
-sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
-sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
-sub_rect->w = av_clip(sub_rect->w, 0, sp->width  - 
sub_rect->x);
-sub_rect->h = av_clip(sub_rect->h, 0, sp->height - 
sub_rect->y);
+area->x = av_clip(area->x, 0, sp->width );
+area->y = av_clip(area->y, 0, sp->height);
+area->w = av_clip(area->w, 0, sp->width  - area->x);
+area->h = av_clip(area->h, 0, sp->height - area->y);
 
 is->sub_convert_ctx = 
sws_getCachedContext(is->sub_convert_ctx,
-sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
-sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
+  

[FFmpeg-devel] [PATCH v2 12/26] avfilter/overlaygraphicsubs: Add overlaygraphicsubs and graphicsub2video filters

2022-01-19 Thread ffmpegagent
From: softworkz 

- overlaygraphicsubs (VS -> V)
  Overlay graphic subtitles onto a video stream

- graphicsub2video {S -> V)
  Converts graphic subtitles to video frames (with alpha)
  Gets auto-inserted for retaining compatibility with
  sub2video command lines

Signed-off-by: softworkz 
---
 doc/filters.texi| 118 +
 libavfilter/Makefile|   2 +
 libavfilter/allfilters.c|   2 +
 libavfilter/vf_overlaygraphicsubs.c | 765 
 4 files changed, 887 insertions(+)
 create mode 100644 libavfilter/vf_overlaygraphicsubs.c

diff --git a/doc/filters.texi b/doc/filters.texi
index 05d4b1a56e..4fc4a57dbb 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -25713,6 +25713,124 @@ tools.
 
 @c man end VIDEO SINKS
 
+@chapter Subtitle Filters
+@c man begin SUBTITLE FILTERS
+
+When you configure your FFmpeg build, you can disable any of the
+existing filters using @code{--disable-filters}.
+
+Below is a description of the currently available subtitle filters.
+
+@section graphicsub2video
+
+Renders graphic subtitles as video frames.
+
+This filter replaces the previous "sub2video" hack which did the conversion 
implicitly and up-front as subtitle filtering wasn't possible at that time.
+To retain compatibility with earlier sub2video command lines, this filter is 
being auto-inserted in those cases.
+
+For overlaying graphicsal subtitles it is recommended to use the 
'overlay_graphicsubs' filter which is more efficient and takes less processing 
resources.
+
+This filter is still useful in cases where the overlay is done with hardware 
acceleration (e.g. overlay_qsv, overlay_vaapi, overlay_cuda) for preparing the 
overlay frames.
+
+Inputs:
+@itemize
+@item 0: Subtitles [BITMAP]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Video [RGB32]
+@end itemize
+
+
+It accepts the following parameters:
+
+@table @option
+@item size, s
+Set the size of the output video frame.
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Overlay PGS subtitles
+(not recommended - better use overlay_graphicsubs)
+@example
+ffmpeg -i 
"https://streams.videolan.org/samples/sub/PGS/Girl_With_The_Dragon_Tattoo_2%3A23%3A56.mkv";
 -filter_complex "[0:1]graphicsub2video[subs];[0:0][subs]overlay" output.mp4
+@end example
+
+@item
+Overlay PGS subtitles implicitly
+The graphicsub2video is inserted automatically for compatibility with legacy 
command lines.
+@example
+ffmpeg -i 
"https://streams.videolan.org/samples/sub/PGS/Girl_With_The_Dragon_Tattoo_2%3A23%3A56.mkv";
 -filter_complex "[0:0][0:1]overlay" output.mp4
+@end example
+@end itemize
+
+@section overlaygraphicsubs
+
+Overlay graphic subtitles onto a video stream.
+
+This filter can blend graphical subtitles on a video stream directly, i.e. 
without creating full-size alpha images first.
+The blending operation is limited to the area of the subtitle rectangles, 
which also means that no processing is done at times where no subtitles are to 
be displayed.
+
+Inputs:
+@itemize
+@item 0: Video [YUV420P, YUV422P, YUV444P, ARGB, RGBA, ABGR, BGRA, RGB24, 
BGR24]
+@item 1: Subtitles [BITMAP]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Video (same as input)
+@end itemize
+
+It accepts the following parameters:
+
+@table @option
+@item x
+@item y
+Set the expression for the x and y coordinates of the overlaid video
+on the main video. Default value is "0" for both expressions. In case
+the expression is invalid, it is set to a huge value (meaning that the
+overlay will not be displayed within the output visible area).
+
+@item eof_action
+See @ref{framesync}.
+
+@item eval
+Set when the expressions for @option{x}, and @option{y} are evaluated.
+
+It accepts the following values:
+@table @samp
+@item init
+only evaluate expressions once during the filter initialization or
+when a command is processed
+
+@item frame
+evaluate expressions for each incoming frame
+@end table
+
+Default value is @samp{frame}.
+
+@item shortest
+See @ref{framesync}.
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Overlay PGS subtitles
+@example
+ffmpeg -i 
"https://streams.videolan.org/samples/sub/PGS/Girl_With_The_Dragon_Tattoo_2%3A23%3A56.mkv";
 -filter_complex "[0:0][0:1]overlaygraphicsubs" output.mp4
+@end example
+@end itemize
+@c man end SUBTITLE FILTERS
+
 @chapter Multimedia Filters
 @c man begin MULTIMEDIA FILTERS
 
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 283dd436cd..a372effc12 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -298,6 +298,7 @@ OBJS-$(CONFIG_GBLUR_FILTER)  += vf_gblur.o
 OBJS-$(CONFIG_GBLUR_VULKAN_FILTER)   += vf_gblur_vulkan.o vulkan.o 
vulkan_filter.o
 OBJS-$(CONFIG_GEQ_FILTER)+= vf_geq.o
 OBJS-$(CONFIG_GRADFUN_FILTER)+= vf_gradfun.o
+OBJS-$(CONFIG_GRAPHICSUB2VIDEO_FILTER)   += vf_overlaygraphicsubs.o 
framesync.o
 OBJS-$(CONFIG_GRAPHMONITOR_FILTER)   += f_graphmonitor.o
 OBJS-$(CONFIG_GRAYWORLD_FIL

[FFmpeg-devel] [PATCH v2 08/26] avfilter/subtitles: Add subtitles.c for subtitle frame allocation

2022-01-19 Thread ffmpegagent
From: softworkz 

Analog to avfilter/video.c and avfilter/audio.c

Signed-off-by: softworkz 
---
 libavfilter/Makefile|  1 +
 libavfilter/avfilter.c  |  4 +++
 libavfilter/internal.h  |  1 +
 libavfilter/subtitles.c | 63 +
 libavfilter/subtitles.h | 44 
 5 files changed, 113 insertions(+)
 create mode 100644 libavfilter/subtitles.c
 create mode 100644 libavfilter/subtitles.h

diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 1adbea75bd..283dd436cd 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -19,6 +19,7 @@ OBJS = allfilters.o   
  \
framequeue.o \
graphdump.o  \
graphparser.o\
+   subtitles.o  \
video.o  \
 
 OBJS-$(HAVE_THREADS) += pthread.o
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 7362bcdab5..df5b8f483c 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -43,6 +43,7 @@
 #include "formats.h"
 #include "framepool.h"
 #include "internal.h"
+#include "subtitles.h"
 
 #include "libavutil/ffversion.h"
 const char av_filter_ffversion[] = "FFmpeg version " FFMPEG_VERSION;
@@ -1475,6 +1476,9 @@ int ff_inlink_make_frame_writable(AVFilterLink *link, 
AVFrame **rframe)
 case AVMEDIA_TYPE_AUDIO:
 out = ff_get_audio_buffer(link, frame->nb_samples);
 break;
+case AVMEDIA_TYPE_SUBTITLE:
+out = ff_get_subtitles_buffer(link, link->format);
+break;
 default:
 return AVERROR(EINVAL);
 }
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index 1099b82b4b..fc09ef574c 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -90,6 +90,7 @@ struct AVFilterPad {
 union {
 AVFrame *(*video)(AVFilterLink *link, int w, int h);
 AVFrame *(*audio)(AVFilterLink *link, int nb_samples);
+AVFrame *(*subtitle)(AVFilterLink *link, int format);
 } get_buffer;
 
 /**
diff --git a/libavfilter/subtitles.c b/libavfilter/subtitles.c
new file mode 100644
index 00..951bfd612c
--- /dev/null
+++ b/libavfilter/subtitles.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/common.h"
+
+#include "subtitles.h"
+#include "avfilter.h"
+#include "internal.h"
+
+
+AVFrame *ff_null_get_subtitles_buffer(AVFilterLink *link, int format)
+{
+return ff_get_subtitles_buffer(link->dst->outputs[0], format);
+}
+
+AVFrame *ff_default_get_subtitles_buffer(AVFilterLink *link, int format)
+{
+AVFrame *frame;
+
+frame = av_frame_alloc();
+if (!frame)
+return NULL;
+
+frame->format = format;
+frame->type = AVMEDIA_TYPE_SUBTITLE;
+
+if (av_frame_get_buffer2(frame, 0) < 0) {
+av_frame_free(&frame);
+return NULL;
+}
+
+return frame;
+}
+
+AVFrame *ff_get_subtitles_buffer(AVFilterLink *link, int format)
+{
+AVFrame *ret = NULL;
+
+if (link->dstpad->get_buffer.subtitle)
+ret = link->dstpad->get_buffer.subtitle(link, format);
+
+if (!ret)
+ret = ff_default_get_subtitles_buffer(link, format);
+
+return ret;
+}
diff --git a/libavfilter/subtitles.h b/libavfilter/subtitles.h
new file mode 100644
index 00..4a9115126e
--- /dev/null
+++ b/libavfilter/subtitles.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * 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

[FFmpeg-devel] [PATCH v2 13/26] avfilter/overlaytextsubs: Add overlaytextsubs and textsubs2video filters

2022-01-19 Thread ffmpegagent
From: softworkz 

- overlaytextsubs {VS -> V)
  Overlay text subtitles onto a video stream.

- textsubs2video {S -> V)
  Converts text subtitles to video frames

Signed-off-by: softworkz 
---
 configure|   2 +
 doc/filters.texi | 113 ++
 libavfilter/Makefile |   2 +
 libavfilter/allfilters.c |   4 +-
 libavfilter/vf_overlaytextsubs.c | 678 +++
 5 files changed, 798 insertions(+), 1 deletion(-)
 create mode 100644 libavfilter/vf_overlaytextsubs.c

diff --git a/configure b/configure
index 7c2931bd50..340a198fa6 100755
--- a/configure
+++ b/configure
@@ -3691,6 +3691,7 @@ overlay_opencl_filter_deps="opencl"
 overlay_qsv_filter_deps="libmfx"
 overlay_qsv_filter_select="qsvvpp"
 overlay_vulkan_filter_deps="vulkan spirv_compiler"
+overlaytextsubs_filter_deps="avcodec libass"
 owdenoise_filter_deps="gpl"
 pad_opencl_filter_deps="opencl"
 pan_filter_deps="swresample"
@@ -3735,6 +3736,7 @@ superequalizer_filter_deps="avcodec"
 superequalizer_filter_select="rdft"
 surround_filter_deps="avcodec"
 surround_filter_select="rdft"
+textsub2video_filter_deps="avcodec libass"
 tinterlace_filter_deps="gpl"
 tinterlace_merge_test_deps="tinterlace_filter"
 tinterlace_pad_test_deps="tinterlace_filter"
diff --git a/doc/filters.texi b/doc/filters.texi
index 4fc4a57dbb..51771f88e4 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -25829,6 +25829,119 @@ Overlay PGS subtitles
 ffmpeg -i 
"https://streams.videolan.org/samples/sub/PGS/Girl_With_The_Dragon_Tattoo_2%3A23%3A56.mkv";
 -filter_complex "[0:0][0:1]overlaygraphicsubs" output.mp4
 @end example
 @end itemize
+
+@section overlaytextsubs
+
+Overlay text subtitles onto a video stream.
+
+This filter supersedes the classic @ref{subtitles} filter opposed to which it 
does no longer require to open and access the source stream separately, which 
is often causing problems or doesn't even work for non-local or slow sources.
+
+Inputs:
+@itemize
+@item 0: Video [YUV420P, YUV422P, YUV444P, ARGB, RGBA, ABGR, BGRA, RGB24, 
BGR24]
+@item 1: Subtitles [TEXT]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Video (same as input)
+@end itemize
+
+It accepts the following parameters:
+
+@table @option
+
+@item alpha
+Process alpha channel, by default alpha channel is untouched.
+
+@item fonts_dir
+Set a directory path containing fonts that can be used by the filter.
+These fonts will be used in addition to whatever the font provider uses.
+
+@item default_font_path
+Path to a font file to be used as the default font.
+
+@item font_size
+Set the default font size.
+
+@item fontconfig_file
+Path to ASS fontconfig configuration file.
+
+@item force_style
+Override default style or script info parameters of the subtitles. It accepts a
+string containing ASS style format @code{KEY=VALUE} couples separated by ",".
+
+@item margin
+Set the rendering margin in pixels.
+
+@item render_latest_only
+For rendering, alway use the latest event only, which is covering the given 
point in time
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Overlay ASS subtitles with animations:
+@example
+ffmpeg -i 
"http://streams.videolan.org/samples/sub/SSA/subtitle_testing_complex.mkv"; 
-filter_complex "[0:v]overlaytextsubs" -map 0 -y out.mkv
+@end example
+@end itemize
+
+@section textsub2video
+
+Converts text subtitles to video frames.
+
+For overlaying text subtitles onto video frames it is recommended to use the 
overlay_textsubs filter.
+The textsub2video is useful for for creating transparent text-frames when 
overlay is done via hw acceleration
+
+Inputs:
+@itemize
+@item 0: Subtitles [TEXT]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Video [RGB32]
+@end itemize
+
+It accepts the following parameters:
+
+@table @option
+
+@item rate, r
+Set the framerate for updating overlay frames.
+Normally, overlay frames will only be updated each time when the subtitles to 
display are changing.
+In cases where subtitles include advanced features (like animation), this 
parameter determines the frequency by which the overlay frames should be 
updated.
+
+@item size, s
+Set the output frame size.
+Allows to override the size of output video frames.
+
+@item fonts_dir
+Set a directory path containing fonts that can be used by the filter.
+These fonts will be used in addition to whatever the font provider uses.
+
+@item default_font_path
+Path to a font file to be used as the default font.
+
+@item font_size
+Set the default font size.
+
+@item fontconfig_file
+Path to ASS fontconfig configuration file.
+
+@item force_style
+Override default style or script info parameters of the subtitles. It accepts a
+string containing ASS style format @code{KEY=VALUE} couples separated by ",".
+
+@item margin
+Set the rendering margin in pixels.
+
+@item render_latest_only
+For rendering, alway use the latest event only, which is covering the given 
point in time.
+@end table
+
 @c man end SUBTITLE FILTERS
 
 @chapter Multimedia Filters
d

[FFmpeg-devel] [PATCH v2 09/26] avfilter/avfilter: Handle subtitle frames

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/avfilter.c  |  8 +---
 libavfilter/avfilter.h  | 11 +++
 libavfilter/avfiltergraph.c |  5 +
 libavfilter/formats.c   | 22 ++
 libavfilter/formats.h   |  3 +++
 libavfilter/internal.h  | 18 +++---
 6 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index df5b8f483c..75d5e86539 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -56,7 +56,8 @@ static void tlog_ref(void *ctx, AVFrame *ref, int end)
 ref->linesize[0], ref->linesize[1], ref->linesize[2], 
ref->linesize[3],
 ref->pts, ref->pkt_pos);
 
-if (ref->width) {
+switch(ref->type) {
+case AVMEDIA_TYPE_VIDEO:
 ff_tlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c",
 ref->sample_aspect_ratio.num, ref->sample_aspect_ratio.den,
 ref->width, ref->height,
@@ -64,12 +65,13 @@ static void tlog_ref(void *ctx, AVFrame *ref, int end)
 ref->top_field_first ? 'T' : 'B',/* Top / Bottom */
 ref->key_frame,
 av_get_picture_type_char(ref->pict_type));
-}
-if (ref->nb_samples) {
+break;
+case AVMEDIA_TYPE_AUDIO:
 ff_tlog(ctx, " cl:%"PRId64"d n:%d r:%d",
 ref->channel_layout,
 ref->nb_samples,
 ref->sample_rate);
+break;
 }
 
 ff_tlog(ctx, "]%s", end ? "\n" : "");
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index b105dc3159..9f917deb41 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -45,6 +45,7 @@
 #include "libavutil/log.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/pixfmt.h"
+#include "libavutil/subfmt.h"
 #include "libavutil/rational.h"
 
 #include "libavfilter/version.h"
@@ -343,6 +344,12 @@ typedef struct AVFilter {
  * and outputs use the same sample rate and channel count/layout.
  */
 const enum AVSampleFormat *samples_list;
+/**
+ * Analogous to pixels, but delimited by AV_SUBTITLE_FMT_NONE
+ * and restricted to filters that only have AVMEDIA_TYPE_SUBTITLE
+ * inputs and outputs.
+ */
+const enum AVSubtitleType *subs_list;
 /**
  * Equivalent to { pix_fmt, AV_PIX_FMT_NONE } as pixels_list.
  */
@@ -351,6 +358,10 @@ typedef struct AVFilter {
  * Equivalent to { sample_fmt, AV_SAMPLE_FMT_NONE } as samples_list.
  */
 enum AVSampleFormat sample_fmt;
+/**
+ * Equivalent to { sub_fmt, AV_SUBTITLE_FMT_NONE } as subs_list.
+ */
+enum AVSubtitleType sub_fmt;
 } formats;
 
 int priv_size;  ///< size of private data to allocate for the filter
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index b8b432e98b..f4987654af 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -311,6 +311,8 @@ static int filter_link_check_formats(void *log, 
AVFilterLink *link, AVFilterForm
 return ret;
 break;
 
+case AVMEDIA_TYPE_SUBTITLE:
+return 0;
 default:
 av_assert0(!"reached");
 }
@@ -441,6 +443,9 @@ static int query_formats(AVFilterGraph *graph, void 
*log_ctx)
 if (!link)
 continue;
 
+if (link->type == AVMEDIA_TYPE_SUBTITLE)
+continue;
+
 neg = ff_filter_get_negotiation(link);
 av_assert0(neg);
 for (neg_step = 1; neg_step < neg->nb_mergers; neg_step++) {
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index ba62f73248..5c972bb183 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/subfmt.h"
 #include "libavutil/avassert.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
@@ -431,6 +432,12 @@ int ff_add_channel_layout(AVFilterChannelLayouts **l, 
uint64_t channel_layout)
 return 0;
 }
 
+int ff_add_subtitle_type(AVFilterFormats **avff, int64_t fmt)
+{
+ADD_FORMAT(avff, fmt, ff_formats_unref, int, formats, nb_formats);
+return 0;
+}
+
 AVFilterFormats *ff_make_formats_list_singleton(int fmt)
 {
 int fmts[2] = { fmt, -1 };
@@ -450,6 +457,13 @@ AVFilterFormats *ff_all_formats(enum AVMediaType type)
 return NULL;
 fmt++;
 }
+} else if (type == AVMEDIA_TYPE_SUBTITLE) {
+if (ff_add_subtitle_type(&ret, AV_SUBTITLE_FMT_BITMAP) < 0)
+return NULL;
+if (ff_add_subtitle_type(&ret, AV_SUBTITLE_FMT_ASS) < 0)
+return NULL;
+if (ff_add_subtitle_type(&ret, AV_SUBTITLE_FMT_TEXT) < 0)
+return NULL;
 }
 
 return ret;
@@ -724,6 +738,10 @@ int ff_default_query_formats(AVFilterContext *ctx)
 type= 

[FFmpeg-devel] [PATCH v2 14/26] avfilter/textmod: Add textmod, censor and show_speaker filters

2022-01-19 Thread ffmpegagent
From: softworkz 

- textmod {S -> S)
  Modify subtitle text in a number of ways

- censor {S -> S)
  Censor subtitles using a word list

- show_speaker {S -> S)
  Prepend speaker names from ASS subtitles to the visible text lines

Signed-off-by: softworkz 
---
 doc/filters.texi | 206 
 libavfilter/Makefile |   5 +
 libavfilter/allfilters.c |   3 +
 libavfilter/sf_textmod.c | 710 +++
 4 files changed, 924 insertions(+)
 create mode 100644 libavfilter/sf_textmod.c

diff --git a/doc/filters.texi b/doc/filters.texi
index 51771f88e4..494ee6f062 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -25721,6 +25721,145 @@ existing filters using @code{--disable-filters}.
 
 Below is a description of the currently available subtitle filters.
 
+
+@section censor
+
+Censor selected words in text subtitles.
+
+Inputs:
+@itemize
+@item 0: Subtitles[TEXT]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Subtitles[TEXT]
+@end itemize
+
+It accepts the following parameters:
+
+@table @option
+@item mode
+The censoring mode to apply.
+
+Supported censoring modes are:
+
+@table @var
+@item 0, keep_first_last
+Replace all characters with the 'censor_char' except the first and the last 
character of a word.
+For words with less than 4 characters, the last character will be replaced as 
well.
+For words with less than 3 characters, the first character will be replaced as 
well.
+@item 1, keep_first
+Replace all characters with the 'censor_char' except the first character of a 
word.
+For words with less than 3 characters, the first character will be replaced as 
well.
+@item 2, all
+Replace all characters with the 'censor_char'.
+@end table
+
+@item words
+A list of words to censor, separated by 'separator'.
+
+@item words_file
+Specify a file from which to load the contents for the 'words' parameter.
+
+@item censor_char
+Single character used as replacement for censoring.
+
+@item separator
+Delimiter character for words. Used with replace_words and remove_words- Must 
be a single character.
+The default is '.'.
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Censor a few given words with a pound character.
+@example
+ffmpeg -i 
"http://streams.videolan.org/samples/sub/SSA/subtitle_testing_complex.mkv"; 
-filter_complex 
"[0:1]censor=words='diss,louder,hope,beam,word':censor_char='#'" -map 0 -y 
output.mkv
+@end example
+@end itemize
+
+
+@section textmod
+
+Modify subtitle text in a number of ways.
+
+Inputs:
+@itemize
+@item 0: Subtitles[TEXT]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Subtitles[TEXT]
+@end itemize
+
+It accepts the following parameters:
+
+@table @option
+@item mode
+The kind of text modification to apply
+
+Supported operation modes are:
+
+@table @var
+@item 0, leet
+Convert subtitle text to 'leet speak'. It's primarily useful for testing as 
the modification will be visible with almost all text lines.
+@item 1, to_upper
+Change all text to upper case. Might improve readability.
+@item 2, to_lower
+Change all text to lower case.
+@item 3, replace_chars
+Replace one or more characters. Requires the find and replace parameters to be 
specified.
+Both need to be equal in length.
+The first char in find is replaced by the first char in replace, same for all 
subsequent chars.
+@item 4, remove_chars
+Remove certain characters. Requires the find parameter to be specified.
+All chars in the find parameter string will be removed from all subtitle text.
+@item 5, replace_words
+Replace one or more words. Requires the find and replace parameters to be 
specified. Multiple words must be separated by the delimiter char specified vie 
the separator parameter (default: ',').
+The number of words in the find and replace parameters needs to be equal.
+The first word in find is replaced by the first word in replace, same for all 
subsequent words
+@item 6, remove_words
+Remove certain words. Requires the find parameter to be specified. Multiple 
words must be separated by the delimiter char specified vie the separator 
parameter (default: ',').
+All words in the find parameter string will be removed from all subtitle text.
+@end table
+
+@item find
+Required for replace_chars, remove_chars, replace_words and remove_words.
+
+@item find_file
+Specify a file from which to load the contents for the 'find' parameter.
+
+@item replace
+Required for replace_chars and replace_words.
+
+@item replace_file
+Specify a file from which to load the contents for the 'replace' parameter.
+
+@item separator
+Delimiter character for words. Used with replace_words and remove_words- Must 
be a single character.
+The default is '.'.
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Change all characters to upper case while keeping all styles and animations:
+@example
+ffmpeg -i "https://streams.videolan.org/ffmpeg/mkv_subtitles.mkv"; 
-filter_complex "[0:s]textmod=mode=to_upper" -map 0 -y out.mkv
+@end example
+@item
+Remove a set of symbol characters for am i

[FFmpeg-devel] [PATCH v2 15/26] avfilter/stripstyles: Add stripstyles filter

2022-01-19 Thread ffmpegagent
From: softworkz 

- stripstyles {S -> S)
  Remove all inline styles from subtitle events

Signed-off-by: softworkz 
---
 doc/filters.texi |  37 ++
 libavfilter/Makefile |   1 +
 libavfilter/allfilters.c |   1 +
 libavfilter/sf_stripstyles.c | 211 +++
 4 files changed, 250 insertions(+)
 create mode 100644 libavfilter/sf_stripstyles.c

diff --git a/doc/filters.texi b/doc/filters.texi
index 494ee6f062..c0f0fe13e7 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -25781,6 +25781,43 @@ ffmpeg -i 
"http://streams.videolan.org/samples/sub/SSA/subtitle_testing_complex.
 @end example
 @end itemize
 
+@section stripstyles
+
+Remove all inline styles from subtitle events.
+
+Inputs:
+@itemize
+@item 0: Subtitles[TEXT]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Subtitles[TEXT]
+@end itemize
+
+It accepts the following parameters:
+
+@table @option
+@item remove_animated
+Also remove text which is subject to animation (default: true)
+Usually, animated text elements are used used in addition to static subtitle 
lines for creating effects, so in most cases it is safe to remove the animation 
content.
+If subtitle text is missing, try setting this to false.
+
+@item select_layer
+Process only ASS subtitle events from a specific layer. This allows to filter 
out certain effects where an ASS author duplicates the text onto multiple 
layers.
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Remove styles and animations from ASS subtitles and output events from ass 
layer 0 only. Then convert asn save as SRT stream:
+@example
+ffmpeg -i 
"https://streams.videolan.org/samples/sub/SSA/subtitle_testing_complex.mkv"; 
-filter_complex "[0:1]stripstyles=select_layer=0" -map 0 -c:s srt output.mkv
+@end example
+@end itemize
+
 
 @section textmod
 
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 1af4f4b9bc..d330020f67 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -565,6 +565,7 @@ OBJS-$(CONFIG_NULLSINK_FILTER)   += 
vsink_nullsink.o
 OBJS-$(CONFIG_CENSOR_FILTER) += sf_textmod.o
 OBJS-$(CONFIG_SHOW_SPEAKER_FILTER)   += sf_textmod.o
 OBJS-$(CONFIG_TEXTMOD_FILTER)+= sf_textmod.o
+OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
 
 # multimedia filters
 OBJS-$(CONFIG_ABITSCOPE_FILTER)  += avf_abitscope.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index ac7d71547b..b0c12595af 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -549,6 +549,7 @@ extern const AVFilter ff_avf_showwavespic;
 extern const AVFilter ff_vaf_spectrumsynth;
 extern const AVFilter ff_sf_censor;
 extern const AVFilter ff_sf_showspeaker;
+extern const AVFilter ff_sf_stripstyles;
 extern const AVFilter ff_sf_textmod;
 extern const AVFilter ff_svf_graphicsub2video;
 extern const AVFilter ff_svf_textsub2video;
diff --git a/libavfilter/sf_stripstyles.c b/libavfilter/sf_stripstyles.c
new file mode 100644
index 00..bc3c5d1441
--- /dev/null
+++ b/libavfilter/sf_stripstyles.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * text subtitle filter which removes inline-styles from subtitles
+ */
+
+#include "libavutil/opt.h"
+#include "internal.h"
+#include "libavutil/ass_split_internal.h"
+#include "libavutil/bprint.h"
+
+typedef struct StripStylesContext {
+const AVClass *class;
+enum AVSubtitleType format;
+int remove_animated;
+int select_layer;
+} StripStylesContext;
+
+typedef struct DialogContext {
+StripStylesContext* ss_ctx;
+AVBPrint buffer;
+int drawing_scale;
+int is_animated;
+} DialogContext;
+
+static void dialog_text_cb(void *priv, const char *text, int len)
+{
+DialogContext *s = priv;
+
+av_log(s->ss_ctx, AV_LOG_DEBUG, "dialog_text_cb: %s\n", text);
+
+if (!s->drawing_scale && (!s->is_animated || !s->ss_ctx->remove_animated))
+av_bprint_append_data(&s->buffer, text, len);
+}
+
+static void dialog_new_line_cb(void *priv, int forced)
+{
+DialogContext *s = priv;
+if (!s->drawing_scale && !s->is_animated)
+av_bprint_append_data(&s->buffer, forced ? "\\N" : "\\n", 2);
+}

[FFmpeg-devel] [PATCH v2 16/26] avfilter/splitcc: Add splitcc filter for closed caption handling

2022-01-19 Thread ffmpegagent
From: softworkz 

- splitcc {V -> VS)
  Extract closed-caption (A53) data from video
  frames as subtitle Frames

ffmpeg -y -loglevel verbose -i "https://streams.videolan.org/streams
/ts/CC/NewsStream-608-ac3.ts" -filter_complex "[0:v]splitcc[vid1],
textmod=mode=remove_chars:find='@',[vid1]overlay_textsubs" output.mkv

Signed-off-by: softworkz 
---
 configure|   1 +
 doc/filters.texi |  63 +++
 libavfilter/Makefile |   1 +
 libavfilter/allfilters.c |   1 +
 libavfilter/sf_splitcc.c | 395 +++
 5 files changed, 461 insertions(+)
 create mode 100644 libavfilter/sf_splitcc.c

diff --git a/configure b/configure
index 340a198fa6..c1d2bc41c2 100755
--- a/configure
+++ b/configure
@@ -3729,6 +3729,7 @@ spp_filter_select="fft idctdsp fdctdsp me_cmp pixblockdsp"
 sr_filter_deps="avformat swscale"
 sr_filter_select="dnn"
 stereo3d_filter_deps="gpl"
+splitcc_filter_deps="avcodec"
 subtitles_filter_deps="avformat avcodec libass"
 super2xsai_filter_deps="gpl"
 pixfmts_super2xsai_test_deps="super2xsai_filter"
diff --git a/doc/filters.texi b/doc/filters.texi
index c0f0fe13e7..265a267e9d 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -26131,6 +26131,69 @@ ffmpeg -i INPUT -filter_complex 
"showspeaker=format=colon:style='@{\\c&HDD&\
 @end example
 @end itemize
 
+
+@section splitcc
+
+Split-out closed-caption/A53 subtitles from video frame side data.
+
+This filter provides an input and an output for video frames, which are just 
passed through without modification.
+The second out provides subtitle frames which are extracted from video frame 
side data.
+
+Inputs:
+@itemize
+@item 0: Video [ALL]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Video (same as input)
+@item 1: Subtitles [TEXT]
+@end itemize
+
+It accepts the following parameters:
+
+@table @option
+
+@item use_cc_styles
+Emit closed caption style header.
+This will make closed captions appear in white font with a black rectangle 
background.
+
+@item real_time
+Emit subtitle events as they are decoded for real-time display.
+
+@item real_time_latency_msec
+Minimum elapsed time between emitting real-time subtitle events.
+Only applies to real_time mode.
+
+@item data_field
+Select data field. Possible values:
+
+@table @samp
+@item auto
+Pick first one that appears.
+@item first
+@item second
+@end table
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Extract closed captions as text subtitle stream and overlay it onto the video 
in cc style (black bar background):
+@example
+ffmpeg -i "https://streams.videolan.org/streams/ts/CC/NewsStream-608-ac3.ts"; 
-filter_complex  
"[0:v:0]splitcc=use_cc_styles=1[vid1][sub1];[vid1][sub1]overlaytextsubs" 
output.mkv
+@end example
+
+@item
+A nicer variant, using realtime output from cc_dec and rendering it with the 
render_latest_only parameter from overlaytextsubs to avoid ghosting by timely 
overlap.
+@example
+ffmpeg -i "https://streams.videolan.org/streams/ts/CC/NewsStream-608-ac3.ts"; 
-filter_complex  
"[0:v:0]splitcc=real_time=1:real_time_latency_msec=200[vid1][sub1];[vid1][sub1]overlaytextsubs=render_latest_only=1"
 output.mkv
+@end example
+@end itemize
+
+
 @section textsub2video
 
 Converts text subtitles to video frames.
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index d330020f67..c6a4a4f5ae 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -565,6 +565,7 @@ OBJS-$(CONFIG_NULLSINK_FILTER)   += 
vsink_nullsink.o
 OBJS-$(CONFIG_CENSOR_FILTER) += sf_textmod.o
 OBJS-$(CONFIG_SHOW_SPEAKER_FILTER)   += sf_textmod.o
 OBJS-$(CONFIG_TEXTMOD_FILTER)+= sf_textmod.o
+OBJS-$(CONFIG_SPLITCC_FILTER)+= sf_splitcc.o
 OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
 
 # multimedia filters
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index b0c12595af..50498e8ec4 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -549,6 +549,7 @@ extern const AVFilter ff_avf_showwavespic;
 extern const AVFilter ff_vaf_spectrumsynth;
 extern const AVFilter ff_sf_censor;
 extern const AVFilter ff_sf_showspeaker;
+extern const AVFilter ff_sf_splitcc;
 extern const AVFilter ff_sf_stripstyles;
 extern const AVFilter ff_sf_textmod;
 extern const AVFilter ff_svf_graphicsub2video;
diff --git a/libavfilter/sf_splitcc.c b/libavfilter/sf_splitcc.c
new file mode 100644
index 00..14235e822c
--- /dev/null
+++ b/libavfilter/sf_splitcc.c
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * 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
+

[FFmpeg-devel] [PATCH v2 17/26] avfilter/graphicsub2text: Add new graphicsub2text filter (OCR)

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 configure|1 +
 doc/filters.texi |   55 ++
 libavfilter/Makefile |2 +
 libavfilter/allfilters.c |1 +
 libavfilter/sf_graphicsub2text.c | 1132 ++
 5 files changed, 1191 insertions(+)
 create mode 100644 libavfilter/sf_graphicsub2text.c

diff --git a/configure b/configure
index c1d2bc41c2..ee7afffb05 100755
--- a/configure
+++ b/configure
@@ -3665,6 +3665,7 @@ frei0r_filter_deps="frei0r"
 frei0r_src_filter_deps="frei0r"
 fspp_filter_deps="gpl"
 gblur_vulkan_filter_deps="vulkan spirv_compiler"
+graphicsub2text_filter_deps="libtesseract"
 hflip_vulkan_filter_deps="vulkan spirv_compiler"
 histeq_filter_deps="gpl"
 hqdn3d_filter_deps="gpl"
diff --git a/doc/filters.texi b/doc/filters.texi
index 265a267e9d..9311714f82 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -25897,6 +25897,61 @@ ffmpeg -i 
"https://streams.videolan.org/ffmpeg/mkv_subtitles.mkv"; -filter_comple
 @end example
 @end itemize
 
+@section graphicsub2text
+
+Converts graphic subtitles to text subtitles by performing OCR.
+
+For this filter to be available, ffmpeg needs to be compiled with libtesseract 
(see https://github.com/tesseract-ocr/tesseract).
+Language models need to be downloaded from 
https://github.com/tesseract-ocr/tessdata and put into as subfolder named 
'tessdata' or into a folder specified via the environment variable 
'TESSDATA_PREFIX'.
+The path can also be specified via filter option (see below).
+
+Note: These models are including the data for both OCR modes.
+
+Inputs:
+- 0: Subtitles [bitmap]
+
+Outputs:
+- 0: Subtitles [text]
+
+It accepts the following parameters:
+
+@table @option
+@item ocr_mode
+The character recognition mode to use.
+
+Supported OCR modes are:
+
+@table @var
+@item 0, tesseract
+This is the classic libtesseract operation mode. It is fast but less accurate 
than LSTM.
+@item 1, lstm
+Newer OCR implementation based on ML models. Provides usually better results, 
requires more processing resources.
+@item 2, both
+Use a combination of both modes.
+@end table
+
+@item tessdata_path
+The path to a folder containing the language models to be used.
+
+@item language
+The recognition language. It needs to match the first three characters of a  
language model file in the tessdata path.
+
+@end table
+
+
+@subsection Examples
+
+@itemize
+@item
+Convert DVB graphic subtitles to ASS (text) subtitles
+
+Note: For this to work, you need to have the data file 'eng.traineddata' in a 
'tessdata' subfolder (see above).
+@example
+ffmpeg -loglevel verbose -i 
"https://streams.videolan.org/streams/ts/video_subs_ttxt%2Bdvbsub.ts"; 
-filter_complex "[0:13]graphicsub2text=delay_when_no_duration=1" -c:s ass -y 
output.mkv
+@end example
+@end itemize
+
+
 @section graphicsub2video
 
 Renders graphic subtitles as video frames.
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index c6a4a4f5ae..ead3e38507 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -299,6 +299,8 @@ OBJS-$(CONFIG_GBLUR_VULKAN_FILTER)   += 
vf_gblur_vulkan.o vulkan.o vulka
 OBJS-$(CONFIG_GEQ_FILTER)+= vf_geq.o
 OBJS-$(CONFIG_GRADFUN_FILTER)+= vf_gradfun.o
 OBJS-$(CONFIG_GRAPHICSUB2VIDEO_FILTER)   += vf_overlaygraphicsubs.o 
framesync.o
+OBJS-$(CONFIG_GRAPHICSUB2TEXT_FILTER)+= sf_graphicsub2text.o
+OBJS-$(CONFIG_GRAPHICSUB2VIDEO_FILTER)   += vf_overlaygraphicsubs.o 
framesync.o
 OBJS-$(CONFIG_GRAPHMONITOR_FILTER)   += f_graphmonitor.o
 OBJS-$(CONFIG_GRAYWORLD_FILTER)  += vf_grayworld.o
 OBJS-$(CONFIG_GREYEDGE_FILTER)   += vf_colorconstancy.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 50498e8ec4..34576016ce 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -548,6 +548,7 @@ extern const AVFilter ff_avf_showwaves;
 extern const AVFilter ff_avf_showwavespic;
 extern const AVFilter ff_vaf_spectrumsynth;
 extern const AVFilter ff_sf_censor;
+extern const AVFilter ff_sf_graphicsub2text;
 extern const AVFilter ff_sf_showspeaker;
 extern const AVFilter ff_sf_splitcc;
 extern const AVFilter ff_sf_stripstyles;
diff --git a/libavfilter/sf_graphicsub2text.c b/libavfilter/sf_graphicsub2text.c
new file mode 100644
index 00..9b413d314e
--- /dev/null
+++ b/libavfilter/sf_graphicsub2text.c
@@ -0,0 +1,1132 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * 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 Gene

[FFmpeg-devel] [PATCH v2 18/26] avfilter/subscale: Add filter for scaling and/or re-arranging graphical subtitles

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 configure |   1 +
 doc/filters.texi  | 164 +++
 libavfilter/Makefile  |   1 +
 libavfilter/allfilters.c  |   1 +
 libavfilter/sf_subscale.c | 884 ++
 5 files changed, 1051 insertions(+)
 create mode 100644 libavfilter/sf_subscale.c

diff --git a/configure b/configure
index ee7afffb05..a8b7ce8a26 100755
--- a/configure
+++ b/configure
@@ -3731,6 +3731,7 @@ sr_filter_deps="avformat swscale"
 sr_filter_select="dnn"
 stereo3d_filter_deps="gpl"
 splitcc_filter_deps="avcodec"
+subscale_filter_deps="swscale avcodec"
 subtitles_filter_deps="avformat avcodec libass"
 super2xsai_filter_deps="gpl"
 pixfmts_super2xsai_test_deps="super2xsai_filter"
diff --git a/doc/filters.texi b/doc/filters.texi
index 9311714f82..b3d11c0ac0 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -26303,6 +26303,170 @@ Set the rendering margin in pixels.
 For rendering, alway use the latest event only, which is covering the given 
point in time.
 @end table
 
+@section subscale
+
+Provides high-quality scaling and rearranging functionality for graphical 
subtitles.
+
+The subscale filter provides multiple approaches for manipulating
+the size and position of graphical subtitle rectangles wich can
+be combined or used separately.
+Scaling is performed by converting the palettized subtitle bitmaps
+to RGBA and re-quantization to palette colors afterwards via elbg algorithm.
+
+The two major operations are 'scale' and 're-arrange' with the
+latter being separated as 'arrange_h' and 'arrange_v'.
+
+
+Inputs:
+- 0: Subtitles [bitmap]
+
+Outputs:
+- 0: Subtitles [bitmap]
+
+It accepts the following parameters:
+
+@table @option
+
+@item w, width
+Set the width of the output.
+Width and height in case of graphical subtitles are just indicating
+a virtual size for which the output (consisting of 0-n bitmap rectangles)
+is intended to be displayed on.
+
+@item h, height
+Set the height of the output.
+
+@item margin_h
+Sets a horizontal margin to be preserverved when using any
+of the arrange modes.
+
+@item margin_v
+Sets a vertical margin to be preserverved when using any
+of the arrange modes.
+
+@item force_original_aspect_ratio
+Enable decreasing or increasing output video width or height if necessary to
+keep the original aspect ratio. Possible values:
+
+@table @samp
+@item disable
+Scale the video as specified and disable this feature.
+
+@item decrease
+The output video dimensions will automatically be decreased if needed.
+
+@item increase
+The output video dimensions will automatically be increased if needed.
+
+@end table
+
+
+@item scale_mode
+Specifies how subtitle bitmaps should be scaled.
+The scale factor is determined by the the factor between input
+and output size.
+
+@table @samp
+@item none
+Do not apply any common scaling.
+
+@item uniform
+Uniformly scale all subtitle bitmaps including their positions.
+
+@item uniform_no_reposition
+Uniformly scale all subtitle bitmaps without changing positions.
+
+@end table
+
+
+@item arrange_h
+Specifies how subtitle bitmaps should be arranged horizontally.
+
+@item arrange_v
+Specifies how subtitle bitmaps should be arranged vertically.
+
+
+@table @samp
+@item none
+Do not rearrange subtitle bitmaps.
+
+@item margin_no_scale
+Move subtitle bitmaps to be positioned inside the specified
+margin (margin_h or margin_v) when possible and without scaling.
+
+@item margin_and_scale
+Move subtitle bitmaps to be positioned inside the specified
+margin (margin_h or margin_v) and scale in case it doesn't fit.
+
+@item snapalign_no_scale
+Categorize subtitle bitmap positions as one of left/center/right
+or top/bottom/middle based on original positioning and apply
+these alignments for the target positioning.
+No scaling will be applied.
+
+@item snapalign_and_scale
+Categorize subtitle bitmap positions as one of left/center/right
+or top/bottom/middle based on original positioning and apply
+these alignments for the target positioning.
+Bitmaps that do not fit inside the margins borders are
+scaled to fit.
+@end table
+
+@item eval
+Set evaluation mode for the expressions (@option{width}, @option{height}).
+
+It accepts the following values:
+@table @samp
+@item init
+Evaluate expressions only once during the filter initialization.
+
+@item frame
+Evaluate expressions for each incoming frame. This is way slower than the
+@samp{init} mode since it requires all the scalers to be re-computed, but it
+allows advanced dynamic expressions.
+@end table
+
+Default value is @samp{init}.
+
+
+@item num_colors
+Set the number of palette colors for output images.
+Choose the maximum (256) when further processing is done (e.g.
+overlaying on a video).
+When subtitles will be encoded as bitmap subtitles (e.g. dvbsub),
+a smaller number of palette colors (e.g. 4-16) might need to be used, depending
+on the target format and codec.
+
+@item bitmap_width_align
+@item bitmap_height_align
+Make s

[FFmpeg-devel] [PATCH v2 19/26] avfilter/subfeed: add subtitle feed filter

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/Makefile |   1 +
 libavfilter/allfilters.c |   1 +
 libavfilter/sf_subfeed.c | 366 +++
 3 files changed, 368 insertions(+)
 create mode 100644 libavfilter/sf_subfeed.c

diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 0e3e48613e..5711c7770b 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -570,6 +570,7 @@ OBJS-$(CONFIG_TEXTMOD_FILTER)+= sf_textmod.o
 OBJS-$(CONFIG_SPLITCC_FILTER)+= sf_splitcc.o
 OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
 OBJS-$(CONFIG_SUBSCALE_FILTER)   += sf_subscale.o
+OBJS-$(CONFIG_SUBFEED_FILTER)+= sf_subfeed.o
 
 # multimedia filters
 OBJS-$(CONFIG_ABITSCOPE_FILTER)  += avf_abitscope.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 8e4f2feca3..10b14b7b8e 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -553,6 +553,7 @@ extern const AVFilter ff_sf_showspeaker;
 extern const AVFilter ff_sf_splitcc;
 extern const AVFilter ff_sf_stripstyles;
 extern const AVFilter ff_sf_subscale;
+extern const AVFilter ff_sf_subfeed;
 extern const AVFilter ff_sf_textmod;
 extern const AVFilter ff_svf_graphicsub2video;
 extern const AVFilter ff_svf_textsub2video;
diff --git a/libavfilter/sf_subfeed.c b/libavfilter/sf_subfeed.c
new file mode 100644
index 00..7df6641f6a
--- /dev/null
+++ b/libavfilter/sf_subfeed.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * subtitle filter for feeding subtitle frames into a filtergraph in a 
contiguous way
+ *
+ *
+ * also supports
+ *   - duration fixup
+ * delaying a subtitle event with unknown duration and infer duration from 
the
+ * start time of the subsequent subtitle
+ *   - scattering
+ * splitting a subtitle event with unknown duration into multiple ones with
+ * a short and fixed duration
+ *
+ */
+
+#include "filters.h"
+#include "libavutil/opt.h"
+#include "subtitles.h"
+#include "libavutil/avassert.h"
+
+enum SubFeedMode {
+FM_REPEAT,
+FM_SCATTER,
+FM_FORWARD,
+};
+
+typedef struct SubFeedContext {
+const AVClass *class;
+enum AVSubtitleType format;
+enum SubFeedMode mode;
+
+AVRational frame_rate;
+int fix_durations;
+int fix_overlap;
+
+int current_frame_isnew;
+int eof;
+int got_first_input;
+int need_frame;
+int64_t next_pts_offset;
+int64_t recent_subtitle_pts;
+
+int64_t counter;
+
+/**
+ * Queue of frames waiting to be filtered.
+ */
+FFFrameQueue fifo;
+
+} SubFeedContext;
+
+static int64_t ms_to_avtb(int64_t ms)
+{
+return av_rescale_q(ms, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q);
+}
+
+static int64_t avtb_to_ms(int64_t avtb)
+{
+return av_rescale_q(avtb, AV_TIME_BASE_Q, (AVRational){ 1, 1000 });
+}
+
+static int init(AVFilterContext *ctx)
+{
+SubFeedContext *s = ctx->priv;
+
+ff_framequeue_init(&s->fifo, NULL);
+
+return 0;
+}
+
+static void uninit(AVFilterContext *ctx)
+{
+SubFeedContext *s = ctx->priv;
+ff_framequeue_free(&s->fifo);
+}
+
+static int config_input(AVFilterLink *link)
+{
+const subfeedContext *context = link->dst->priv;
+
+return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+AVFilterFormats *formats;
+AVFilterLink *inlink0 = ctx->inputs[0];
+AVFilterLink *outlink0 = ctx->outputs[0];
+static const enum AVSubtitleType subtitle_fmts[] = { 
AV_SUBTITLE_FMT_BITMAP, AV_SUBTITLE_FMT_ASS, AV_SUBTITLE_FMT_NB };
+int ret;
+
+formats = ff_make_format_list(subtitle_fmts);
+
+if ((ret = ff_formats_ref(formats, &inlink0->outcfg.formats)) < 0)
+return ret;
+
+if ((ret = ff_formats_ref(formats, &outlink0->incfg.formats)) < 0)
+return ret;
+
+return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+SubFeedContext *s = outlink->src->priv;
+const AVFilterLink *inlink = outlink->src->inputs[0];
+
+outlink->time_base = AV_TIME_BASE_Q;
+outlink->format = inlink->format;
+outlink->w = inlink->w;
+outlink->h = inlink->h;
+
+if (s->mode == FM_FORWARD)
+

[FFmpeg-devel] [PATCH v2 20/26] avcodec/subtitles: Migrate subtitle encoders to frame-based API

2022-01-19 Thread ffmpegagent
From: softworkz 

and provide a compatibility shim for the legacy api

Signed-off-by: softworkz 
---
 libavcodec/assenc.c| 189 ++---
 libavcodec/avcodec.h   |   5 +-
 libavcodec/dvbsubenc.c |  96 ++-
 libavcodec/dvdsubenc.c | 102 
 libavcodec/encode.c|  61 +++-
 libavcodec/movtextenc.c| 114 --
 libavcodec/srtenc.c| 108 ++---
 libavcodec/tests/avcodec.c |   2 -
 libavcodec/ttmlenc.c   | 101 +++-
 libavcodec/webvttenc.c |  86 -
 libavcodec/xsubenc.c   |  88 ++---
 11 files changed, 687 insertions(+), 265 deletions(-)

diff --git a/libavcodec/assenc.c b/libavcodec/assenc.c
index b0e475834b..e1401b1ac5 100644
--- a/libavcodec/assenc.c
+++ b/libavcodec/assenc.c
@@ -22,70 +22,195 @@
 #include 
 
 #include "avcodec.h"
+#include "encode.h"
 #include "libavutil/ass_internal.h"
 #include "internal.h"
 #include "libavutil/avstring.h"
 #include "libavutil/internal.h"
 #include "libavutil/mem.h"
 
+typedef struct {
+AVCodecContext *avctx;
+AVFrame* current_frame;
+int have_frame;
+int current_area;
+} AssEncContext;
+
+static void check_write_header(AVCodecContext* avctx, const AVFrame* frame)
+{
+if (avctx->extradata_size)
+return;
+
+if (frame->subtitle_header && frame->subtitle_header->size > 0) {
+const char* subtitle_header = (char*)frame->subtitle_header->data;
+avctx->extradata_size = strlen(subtitle_header);
+avctx->extradata = av_mallocz(frame->subtitle_header->size + 1);
+memcpy(avctx->extradata, subtitle_header, avctx->extradata_size);
+avctx->extradata[avctx->extradata_size] = 0;
+}
+
+if (!avctx->extradata_size) {
+const char* subtitle_header = 
avpriv_ass_get_subtitle_header_default(0);
+if (!subtitle_header)
+return;
+
+avctx->extradata_size = strlen(subtitle_header);
+avctx->extradata = av_mallocz(avctx->extradata_size + 1);
+memcpy(avctx->extradata, subtitle_header, avctx->extradata_size);
+avctx->extradata[avctx->extradata_size] = 0;
+av_freep(&subtitle_header);
+}
+}
+
 static av_cold int ass_encode_init(AVCodecContext *avctx)
 {
-avctx->extradata = av_malloc(avctx->subtitle_header_size + 1);
-if (!avctx->extradata)
-return AVERROR(ENOMEM);
-memcpy(avctx->extradata, avctx->subtitle_header, 
avctx->subtitle_header_size);
-avctx->extradata_size = avctx->subtitle_header_size;
-avctx->extradata[avctx->extradata_size] = 0;
+AssEncContext *s = avctx->priv_data;
+
+if (avctx->subtitle_header_size) {
+avctx->extradata = av_malloc(avctx->subtitle_header_size + 1);
+if (!avctx->extradata)
+return AVERROR(ENOMEM);
+memcpy(avctx->extradata, avctx->subtitle_header, 
avctx->subtitle_header_size);
+avctx->extradata_size   = avctx->subtitle_header_size;
+avctx->extradata[avctx->extradata_size] = 0;
+}
+
+s->current_frame = av_frame_alloc();
+return 0;
+}
+
+static av_cold int ass_encode_close(AVCodecContext *avctx)
+{
+AssEncContext *s = avctx->priv_data;
+av_frame_free(&s->current_frame);
 return 0;
 }
 
-static int ass_encode_frame(AVCodecContext *avctx,
-unsigned char *buf, int bufsize,
-const AVSubtitle *sub)
+static int ass_encode_frame(AVCodecContext* avctx, AVPacket* avpkt,
+const AVFrame* frame, int* got_packet)
+{
+int ret;
+size_t req_len = 0, total_len = 0;
+
+check_write_header(avctx, frame);
+
+for (unsigned i = 0; i < frame->num_subtitle_areas; i++) {
+const char *ass = frame->subtitle_areas[i]->ass;
+
+if (frame->subtitle_areas[i]->type != AV_SUBTITLE_FMT_ASS) {
+av_log(avctx, AV_LOG_ERROR, "Only AV_SUBTITLE_FMT_ASS type 
supported.\n");
+return AVERROR(EINVAL);
+}
+
+if (ass)
+req_len += strlen(ass);
+}
+
+ret = ff_get_encode_buffer(avctx, avpkt, req_len + 1, 0);
+if (ret < 0) {
+av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+return ret;
+}
+
+for (unsigned i = 0; i < frame->num_subtitle_areas; i++) {
+const char *ass = frame->subtitle_areas[i]->ass;
+
+if (ass) {
+size_t len = av_strlcpy((char *)avpkt->data + total_len, ass, 
avpkt->size - total_len);
+total_len += len;
+}
+}
+
+avpkt->size = total_len;
+*got_packet = total_len > 0;
+
+return 0;
+}
+
+static int ass_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
 {
-int i, len, total_len = 0;
+AssEncContext *s = avctx-

[FFmpeg-devel] [PATCH v2 22/26] avutil/ass_split: Add parsing of hard-space tags (\h)

2022-01-19 Thread ffmpegagent
From: softworkz 

The \h tag in ASS/SSA is indicating a non-breaking space. See
https://github.com/Aegisub/aegisite/blob/master/source/docs/3.2/
ASS_Tags.html.md

The ass_split implementation is used by almost all text subtitle
encoders and it didn't handle this tag. Interestingly, several
tests are testing for \h parsing and had incorrect reference data
for those tests.

The \h tag is specific to ASS and doesn't have any meaning outside
of ASS.
Still, the reference data for ttmlenc, textenc and webvttenc were
full of \h tags even though this tag doesn't have a meaning there.

Signed-off-by: softworkz 
---
 libavutil/ass_split.c|  7 +++
 tests/ref/fate/.gitattributes|  3 +++
 tests/ref/fate/mov-mp4-ttml-dfxp |  8 
 tests/ref/fate/mov-mp4-ttml-stpp |  8 
 tests/ref/fate/sub-textenc   | 10 +-
 tests/ref/fate/sub-ttmlenc   |  8 
 tests/ref/fate/sub-webvttenc | 10 +-
 7 files changed, 32 insertions(+), 22 deletions(-)
 create mode 100644 tests/ref/fate/.gitattributes

diff --git a/libavutil/ass_split.c b/libavutil/ass_split.c
index c5963351fc..30512dfc74 100644
--- a/libavutil/ass_split.c
+++ b/libavutil/ass_split.c
@@ -484,6 +484,7 @@ int avpriv_ass_split_override_codes(const ASSCodesCallbacks 
*callbacks, void *pr
 while (buf && *buf) {
 if (text && callbacks->text &&
 (sscanf(buf, "\\%1[nN]", new_line) == 1 ||
+ sscanf(buf, "\\%1[hH]", new_line) == 1 ||
  !strncmp(buf, "{\\", 2))) {
 callbacks->text(priv, text, text_len);
 text = NULL;
@@ -492,6 +493,12 @@ int avpriv_ass_split_override_codes(const 
ASSCodesCallbacks *callbacks, void *pr
 if (callbacks->new_line)
 callbacks->new_line(priv, new_line[0] == 'N');
 buf += 2;
+} else if (sscanf(buf, "\\%1[hH]", new_line) == 1) {
+if (callbacks->hard_space)
+callbacks->hard_space(priv);
+else if (callbacks->text)
+callbacks->text(priv, " ", 1);
+buf += 2;
 } else if (!strncmp(buf, "{\\", 2)) {
 buf++;
 while (*buf == '\\') {
diff --git a/tests/ref/fate/.gitattributes b/tests/ref/fate/.gitattributes
new file mode 100644
index 00..19be64d085
--- /dev/null
+++ b/tests/ref/fate/.gitattributes
@@ -0,0 +1,3 @@
+sub-textenc -diff
+sub-ttmlenc -diff
+sub-webvttenc -diff
diff --git a/tests/ref/fate/mov-mp4-ttml-dfxp b/tests/ref/fate/mov-mp4-ttml-dfxp
index e24b5d618b..e565ffa1f6 100644
--- a/tests/ref/fate/mov-mp4-ttml-dfxp
+++ b/tests/ref/fate/mov-mp4-ttml-dfxp
@@ -1,9 +1,9 @@
-2e7e01c821c111466e7a2844826b7f6d *tests/data/fate/mov-mp4-ttml-dfxp.mp4
-8519 tests/data/fate/mov-mp4-ttml-dfxp.mp4
+658884e1b789e75c454b25bdf71283c9 *tests/data/fate/mov-mp4-ttml-dfxp.mp4
+8486 tests/data/fate/mov-mp4-ttml-dfxp.mp4
 #tb 0: 1/1000
 #media_type 0: data
 #codec_id 0: none
-0,  0,  0,68500, 7866, 0x456c36b7
+0,  0,  0,68500, 7833, 0x31b22193
 {
 "packets": [
 {
@@ -15,7 +15,7 @@
 "dts_time": "0.00",
 "duration": 68500,
 "duration_time": "68.50",
-"size": "7866",
+"size": "7833",
 "pos": "44",
 "flags": "K_"
 }
diff --git a/tests/ref/fate/mov-mp4-ttml-stpp b/tests/ref/fate/mov-mp4-ttml-stpp
index 77bd23b7bf..f25b5b2d28 100644
--- a/tests/ref/fate/mov-mp4-ttml-stpp
+++ b/tests/ref/fate/mov-mp4-ttml-stpp
@@ -1,9 +1,9 @@
-cbd2c7ff864a663b0d893deac5a0caec *tests/data/fate/mov-mp4-ttml-stpp.mp4
-8547 tests/data/fate/mov-mp4-ttml-stpp.mp4
+c9570de0ccebc858b0c662a7e449582c *tests/data/fate/mov-mp4-ttml-stpp.mp4
+8514 tests/data/fate/mov-mp4-ttml-stpp.mp4
 #tb 0: 1/1000
 #media_type 0: data
 #codec_id 0: none
-0,  0,  0,68500, 7866, 0x456c36b7
+0,  0,  0,68500, 7833, 0x31b22193
 {
 "packets": [
 {
@@ -15,7 +15,7 @@ cbd2c7ff864a663b0d893deac5a0caec 
*tests/data/fate/mov-mp4-ttml-stpp.mp4
 "dts_time": "0.00",
 "duration": 68500,
 "duration_time": "68.50",
-"size": "7866",
+"size": "7833",
 "pos": "44",
 "flags": "K_"
 }
diff --git a/tests/ref/fate/sub-textenc b/tests/ref/fate/sub-textenc
index 3ea56b38f0..910ca3d6e3 100644
--- a/tests/ref/fate/sub-textenc
+++ b/tests/ref/fate/sub-textenc
@@ -160,18 +160,18 @@ but show this: {normal text}
 \ N is a forced line break
 \ h is a hard space
 Normal spaces at the start and at the end of the line are trimmed while hard 
spaces are not trimmed.
-The\hline\hwill\hnever\hbreak\hautomatically\hright\hbefore\hor\hafter\ha\hhard\hspace.\h:-D
+The line will never break automatically right before or after a hard space. :-D
 
 31
 00:00:54,501 --> 00:00:56,500
 
-\h\h\h\h\hA (05 hard spaces followed by a letter)
+ A (05 hard spaces followed by a let

[FFmpeg-devel] [PATCH v2 23/26] avcodec/webvttenc: convert hard-space tags to  

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/webvttenc.c   |  6 ++
 tests/ref/fate/sub-webvttenc | 10 +-
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/libavcodec/webvttenc.c b/libavcodec/webvttenc.c
index c0436f5739..48945dcb8e 100644
--- a/libavcodec/webvttenc.c
+++ b/libavcodec/webvttenc.c
@@ -123,6 +123,11 @@ static void webvtt_new_line_cb(void *priv, int forced)
 webvtt_print(priv, "\n");
 }
 
+static void webvtt_hard_space_cb(void *priv)
+{
+webvtt_print(priv, " ");
+}
+
 static void webvtt_style_cb(void *priv, char style, int close)
 {
 if (style == 's') // strikethrough unsupported
@@ -147,6 +152,7 @@ static void webvtt_end_cb(void *priv)
 static const ASSCodesCallbacks webvtt_callbacks = {
 .text = webvtt_text_cb,
 .new_line = webvtt_new_line_cb,
+.hard_space   = webvtt_hard_space_cb,
 .style= webvtt_style_cb,
 .color= NULL,
 .font_name= NULL,
diff --git a/tests/ref/fate/sub-webvttenc b/tests/ref/fate/sub-webvttenc
index f4172dcc84..ee9de2859e 100644
--- a/tests/ref/fate/sub-webvttenc
+++ b/tests/ref/fate/sub-webvttenc
@@ -132,26 +132,26 @@ but show this: {normal text}
 \ N is a forced line break
 \ h is a hard space
 Normal spaces at the start and at the end of the line are trimmed while hard 
spaces are not trimmed.
-The line will never break automatically right before or after a hard space. :-D
+The line will never break automatically right before or after a hard space. :-D
 
 00:54.501 --> 00:56.500
 
- A (05 hard spaces followed by a letter)
+ A (05 hard spaces followed by a letter)
 A (Normal  spaces followed by a letter)
 A (No hard spaces followed by a letter)
 
 00:56.501 --> 00:58.500
- A (05 hard spaces followed by a letter)
+ A (05 hard spaces followed by a letter)
 A (Normal  spaces followed by a letter)
 A (No hard spaces followed by a letter)
 Show this: \TEST and this: \-)
 
 00:58.501 --> 01:00.500
 
-A letter followed by 05 hard spaces: A 
+A letter followed by 05 hard spaces: A 
 A letter followed by normal  spaces: A
 A letter followed by no hard spaces: A
-05 hard  spaces between letters: A A
+05 hard  spaces between letters: A A
 5 normal spaces between letters: A A
 
 ^--Forced line break
-- 
ffmpeg-codebot

___
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 24/26] doc/APIchanges: update for subtitle filtering changes

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 doc/APIchanges   | 24 
 libavcodec/version.h |  2 +-
 libavutil/version.h  |  2 +-
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 8df0364e4c..c8238fb008 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,30 @@ libavutil: 2021-04-27
 
 API changes, most recent first:
 
+2021-12-05 - xx - lavc 59.15.100 - avcodec.h
+  Deprecate avcodec_encode_subtitle(), use regular encode api now
+
+2021-12-05 - xx - lavc 59.15.100 - codec_desc.h
+  Add avcodec_descriptor_get_subtitle_format()
+
+2021-12-05 - xx - lavc 59.15.100 - avcodec.h
+  Deprecate avsubtitle_free()
+  Deprecate avcodec_decode_subtitle2(), use regular decode api now
+
+2021-12-05 - xx - lavu 57.11.100 - frame.h
+  Add AVMediaType field to AVFrame
+  Add Fields for carrying subtitle data to AVFrame
+  (subtitle_areas, subtitle_header, subtitle_pts, start/end time, etc.)
+  Add av_frame_get_buffer2() and deprecate av_frame_get_buffer()
+
+2021-12-05 - xx - lavu 57.11.100 - subfmt.h
+  Add struct AVSubtitleArea (replaces AVSubtitle)
+  Add av_get_subtitle_fmt_name() and av_get_subtitle_fmt()
+
+2021-12-05 - xx - lavu 57.11.100 - subfmt.h
+  Add enum AVSubtitleType (moved from lavc), add new values, deprecate existing
+
+2021-11-xx - xx - lavfi 8.19.100 - avfilter.h
 2022-01-04 - 78dc21b123e - lavu 57.16.100 - frame.h
   Add AV_FRAME_DATA_DOVI_METADATA.
 
diff --git a/libavcodec/version.h b/libavcodec/version.h
index a46fb05f1a..b5867ad041 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -28,7 +28,7 @@
 #include "libavutil/version.h"
 
 #define LIBAVCODEC_VERSION_MAJOR  59
-#define LIBAVCODEC_VERSION_MINOR  20
+#define LIBAVCODEC_VERSION_MINOR  21
 #define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
diff --git a/libavutil/version.h b/libavutil/version.h
index 5bf48f6304..168e24f410 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,7 +79,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  57
-#define LIBAVUTIL_VERSION_MINOR  18
+#define LIBAVUTIL_VERSION_MINOR  19
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
-- 
ffmpeg-codebot

___
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 25/26] avcodec/webvttenc: Don't encode drawing codes and empty lines

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/webvttenc.c | 31 +++
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/libavcodec/webvttenc.c b/libavcodec/webvttenc.c
index 48945dcb8e..62c4aa7ffd 100644
--- a/libavcodec/webvttenc.c
+++ b/libavcodec/webvttenc.c
@@ -39,6 +39,8 @@ typedef struct {
 int count;
 char stack[WEBVTT_STACK_SIZE];
 int stack_ptr;
+int has_text;
+int drawing_scale;
 } WebVTTContext;
 
 #ifdef __GNUC__
@@ -115,17 +117,24 @@ static void webvtt_style_apply(WebVTTContext *s, const 
char *style)
 static void webvtt_text_cb(void *priv, const char *text, int len)
 {
 WebVTTContext *s = priv;
-av_bprint_append_data(&s->buffer, text, len);
+if (!s->drawing_scale) {
+av_bprint_append_data(&s->buffer, text, len);
+s->has_text = 1;
+}
 }
 
 static void webvtt_new_line_cb(void *priv, int forced)
 {
-webvtt_print(priv, "\n");
+WebVTTContext *s = priv;
+if (!s->drawing_scale)
+webvtt_print(priv, "\n");
 }
 
 static void webvtt_hard_space_cb(void *priv)
 {
-webvtt_print(priv, " ");
+WebVTTContext *s = priv;
+if (!s->drawing_scale)
+webvtt_print(priv, " ");
 }
 
 static void webvtt_style_cb(void *priv, char style, int close)
@@ -149,6 +158,12 @@ static void webvtt_end_cb(void *priv)
 webvtt_stack_push_pop(priv, 0, 1);
 }
 
+static void dialog_drawing_mode_cb(void *priv, int scale)
+{
+WebVTTContext *s = priv;
+s->drawing_scale = scale;
+}
+
 static const ASSCodesCallbacks webvtt_callbacks = {
 .text = webvtt_text_cb,
 .new_line = webvtt_new_line_cb,
@@ -161,6 +176,7 @@ static const ASSCodesCallbacks webvtt_callbacks = {
 .cancel_overrides = webvtt_cancel_overrides_cb,
 .move = NULL,
 .end  = webvtt_end_cb,
+.drawing_mode = dialog_drawing_mode_cb,
 };
 
 static void ensure_ass_context(WebVTTContext* s, const AVFrame* frame)
@@ -211,16 +227,23 @@ static int webvtt_encode_frame(AVCodecContext* avctx, 
AVPacket* avpkt,
 }
 
 if (ass) {
+const unsigned saved_len = s->buffer.len;
 
-if (i > 0)
+if (i > 0 && s->buffer.len > 0)
 webvtt_new_line_cb(s, 0);
 
+s->drawing_scale = 0;
+s->has_text = 0;
+
 dialog = avpriv_ass_split_dialog(s->ass_ctx, ass);
 if (!dialog)
 return AVERROR(ENOMEM);
 webvtt_style_apply(s, dialog->style);
 avpriv_ass_split_override_codes(&webvtt_callbacks, s, 
dialog->text);
 avpriv_ass_free_dialog(&dialog);
+
+if (!s->has_text)
+s->buffer.len = saved_len;
 }
 }
 
-- 
ffmpeg-codebot

___
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 26/26] avcodec/dvbsubdec: Fix conditions for fallback to default resolution

2022-01-19 Thread ffmpegagent
From: softworkz 

The previous code expected a segment of type CLUT definition to exist
in order to accept a set of segments to be complete.
This was an incorrect assumption as the presence of a CLUT segment
is not mandatory.
(version 1.6.1 of the spec is probably a bit more clear about this
than earlier versions: https://www.etsi.org/deliver/etsi_en/
300700_300799/300743/01.06.01_20/en_300743v010601a.pdf)

The flawed condition prevented proper fallback to using the default
resolution for the decoding context.

Signed-off-by: softworkz 
---
 libavcodec/dvbsubdec.c | 51 +-
 1 file changed, 30 insertions(+), 21 deletions(-)

diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c
index 0d64c6e71c..3a6259101c 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -33,7 +33,7 @@
 #define DVBSUB_CLUT_SEGMENT 0x12
 #define DVBSUB_OBJECT_SEGMENT   0x13
 #define DVBSUB_DISPLAYDEFINITION_SEGMENT 0x14
-#define DVBSUB_DISPLAY_SEGMENT  0x80
+#define DVBSUB_END_DISPLAY_SEGMENT  0x80
 
 #define cm (ff_crop_tab + MAX_NEG_CROP)
 
@@ -1620,8 +1620,12 @@ static int dvbsub_decode(AVCodecContext *avctx,
 int segment_length;
 int i;
 int ret = 0;
-int got_segment = 0;
-int got_dds = 0;
+//int got_segment = 0;
+int got_page = 0;
+int got_region = 0;
+int got_object = 0;
+int got_end_display = 0;
+int got_displaydef = 0;
 
 ff_dlog(avctx, "DVB sub packet:\n");
 
@@ -1666,34 +1670,28 @@ static int dvbsub_decode(AVCodecContext *avctx,
 switch (segment_type) {
 case DVBSUB_PAGE_SEGMENT:
 ret = dvbsub_parse_page_segment(avctx, p, segment_length, sub, 
got_sub_ptr);
-got_segment |= 1;
+got_page = 1;
 break;
 case DVBSUB_REGION_SEGMENT:
 ret = dvbsub_parse_region_segment(avctx, p, segment_length);
-got_segment |= 2;
+got_region = 1;
 break;
 case DVBSUB_CLUT_SEGMENT:
 ret = dvbsub_parse_clut_segment(avctx, p, segment_length);
 if (ret < 0) goto end;
-got_segment |= 4;
 break;
 case DVBSUB_OBJECT_SEGMENT:
 ret = dvbsub_parse_object_segment(avctx, p, segment_length);
-got_segment |= 8;
+got_object = 1;
 break;
 case DVBSUB_DISPLAYDEFINITION_SEGMENT:
 ret = dvbsub_parse_display_definition_segment(avctx, p,
   segment_length);
-got_dds = 1;
+got_displaydef = 1;
 break;
-case DVBSUB_DISPLAY_SEGMENT:
+case DVBSUB_END_DISPLAY_SEGMENT:
 ret = dvbsub_display_end_segment(avctx, p, segment_length, 
sub, got_sub_ptr);
-if (got_segment == 15 && !got_dds && !avctx->width && 
!avctx->height) {
-// Default from ETSI EN 300 743 V1.3.1 (7.2.1)
-avctx->width  = 720;
-avctx->height = 576;
-}
-got_segment |= 16;
+got_end_display = 1;
 break;
 default:
 ff_dlog(avctx, "Subtitling segment type 0x%x, page id %d, 
length %d\n",
@@ -1706,13 +1704,24 @@ static int dvbsub_decode(AVCodecContext *avctx,
 
 p += segment_length;
 }
-// Some streams do not send a display segment but if we have all the other
-// segments then we need no further data.
-if (got_segment == 15) {
-av_log(avctx, AV_LOG_DEBUG, "Missing display_end_segment, 
emulating\n");
-dvbsub_display_end_segment(avctx, p, 0, sub, got_sub_ptr);
-}
 
+// Even though not mandated by the spec, we're imposing a minimum 
requirement
+// for a useful packet to have at least one page, region and object 
segment.
+if (got_page && got_region && got_object && got_end_display) {
+
+if (!got_displaydef && !avctx->width && !avctx->height) {
+// Default from ETSI EN 300 743 V1.3.1 (7.2.1)
+avctx->width  = 720;
+avctx->height = 576;
+}
+
+// Some streams do not send an end-of-display segment but if we have 
all the other
+// segments then we need no further data.
+if (!got_end_display) {
+av_log(avctx, AV_LOG_DEBUG, "Missing display_end_segment, 
emulating\n");
+dvbsub_display_end_segment(avctx, p, 0, sub, got_sub_ptr);
+}
+}
 end:
 if (ret < 0) {
 return ret;
-- 
ffmpeg-codebot
___
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 v3 00/26] Subtitle Filtering 2022

2022-01-19 Thread ffmpegagent


Subtitle Filtering 2022
===

This is a substantial update to the earlier subtitle filtering patch series.
A primary goal has been to address others' concerns as much as possible on
one side and to provide more clarity and control over the way things are
working. Clarity is is specifically important to allow for a better
understanding of the need for a subtitle start pts value that can be
different from the frame's pts value. This is done by refactoring the
subtitle timing fields in AVFrame, adding a frame field to indicate repeated
subtitle frames, and finally the full removal of the heartbeat
functionality, replaced by a new 'subfeed' filter that provides different
modes for arbitrating subtitle frames in a filter graph. Finally, each
subtitle filter's documentation has been amended by a section describing the
filter's timeline behavior (in v3 update).

The update also includes major improvements to graphicsub2text and lots of
other details.

Versioning is restarting at v1 due to the new submission procedure.


v3 - Rebase
===

due to merge conflicts - apologies.


Changes in v2
=

 * added .gitattributes file to enforce binary diffs for the test refs that
   cannot be applied when being sent via e-mail
 * perform filter graph re-init due to subtitle "frame size" change only
   when the size was unknown before and not set via -canvas_size
 * overlaytextsubs: Make sure to request frames on the subtitle input
 * avfilter/splitcc: Start parsing cc data on key frames only
 * avcodec/webvttenc: Don't encode ass drawing codes and empty lines
 * stripstyles: fix mem leak
 * gs2t: improve color detection
 * gs2t: empty frames must not be skipped
 * subfeed: fix name
 * textmod: preserve margins
 * added .gitattributes file to enforce binary diffs for the test refs that
   cannot be applied when being sent via e-mail
 * perform filter graph re-init due to subtitle "frame size" change only
   when the size was unknown before and not set via -canvas_size
 * avcodec/dvbsubdec: Fix conditions for fallback to default resolution
 * Made changes suggested by Andreas
 * Fixed failing command line reported by Michael

Changes from previous version v24:


AVFrame
===

 * Removed sub_start_time The start time is now added to the subtitle
   start_pts during decoding The sub_end_time field is adjusted accordingly
 * Renamed sub_end_time to duration which it is effectively after removing
   the start_time
 * Added a sub-struct 'subtitle_timing' to av frame Contains subtitle_pts
   renamed to 'subtitle_timing.start_pts' and 'subtitle_timing.duration'
 * Change both fields to (fixed) time_base AV_TIMEBASE
 * add repeat_sub field provides a clear indication whether a subtitle frame
   is an actual subtitle event or a repeated subtitle frame in a filter
   graph


Heartbeat Removal
=

 * completely removed the earlier heartbeat implementation
 * filtering arbitration is now implemented in a new filter: 'subfeed'
 * subfeed will be auto-inserted for compatiblity with sub2video command
   lines
 * the new behavior is not exactly identical to the earlier behavior, but it
   basically allows to achieve the same results


New 'subfeed' Filter


 * a versatile filter for solving all kinds of problems with subtile frame
   flow in filter graphs
 * Can be inserted at any position in a graph
 * Auto-inserted for sub2video command lines (in repeat-mode)
 * Allows duration fixup delay input frames with unknown duration and infer
   duration from start of subsequent frame
 * Provides multiple modes of operation:
   * repeat mode (default) Queues input frames Outputs frames at a fixed
 (configurable) rate Either sends a matching input frame (repeatedly) or
 empty frames otherwise
   * scatter mode similar to repeat mode, but splits input frames by
 duration into small segments with same content
   * forward mode No fixed output rate Useful in combination with duration
 fixup or overlap fixup


ffmpeg Tool Changes
===

 * delay subtitle output stream initialization (like for audio and video)
   This is needed for example when a format header depends on having
   received an initial frame to derive certain header values from
 * decoding: set subtitle frame size from decoding context
 * re-init graph when subtitle size changes
 * always insert subscale filter for sub2video command lines (to ensure
   correct scaling)


Subtitle Encoding
=

 * ignore repeated frames for encoding based on repeat_sub field in AVFrame
 * support multi-area encoding for text subtitles Subtitle OCR can create
   multiple areas at different positions. Previously, the texts were always
   squashed into a single area ('subtitle rect'), which was not ideal.
   Multiple text areas are now generally supported:
   * ASS Encoder Changed to use the 'receive_packet' encoding API A single
 frame with multiple text areas will create multiple packets

[FFmpeg-devel] [PATCH v3 01/26] avcodec, avutil: Move enum AVSubtitleType to avutil, add new and deprecate old values

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/avcodec.h | 19 +
 libavutil/Makefile   |  1 +
 libavutil/subfmt.h   | 68 
 libavutil/version.h  |  1 +
 4 files changed, 71 insertions(+), 18 deletions(-)
 create mode 100644 libavutil/subfmt.h

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index ec1a0566a4..fe5a83cf85 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -35,6 +35,7 @@
 #include "libavutil/frame.h"
 #include "libavutil/log.h"
 #include "libavutil/pixfmt.h"
+#include "libavutil/subfmt.h"
 #include "libavutil/rational.h"
 
 #include "codec.h"
@@ -2238,24 +2239,6 @@ typedef struct AVHWAccel {
  * @}
  */
 
-enum AVSubtitleType {
-SUBTITLE_NONE,
-
-SUBTITLE_BITMAP,///< A bitmap, pict will be set
-
-/**
- * Plain text, the text field must be set by the decoder and is
- * authoritative. ass and pict fields may contain approximations.
- */
-SUBTITLE_TEXT,
-
-/**
- * Formatted text, the ass field must be set by the decoder and is
- * authoritative. pict and text fields may contain approximations.
- */
-SUBTITLE_ASS,
-};
-
 #define AV_SUBTITLE_FLAG_FORCED 0x0001
 
 typedef struct AVSubtitleRect {
diff --git a/libavutil/Makefile b/libavutil/Makefile
index d17876df1a..ce644f4d48 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -74,6 +74,7 @@ HEADERS = adler32.h   
  \
   sha512.h  \
   spherical.h   \
   stereo3d.h\
+  subfmt.h  \
   threadmessage.h   \
   time.h\
   timecode.h\
diff --git a/libavutil/subfmt.h b/libavutil/subfmt.h
new file mode 100644
index 00..791b45519f
--- /dev/null
+++ b/libavutil/subfmt.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * 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_SUBFMT_H
+#define AVUTIL_SUBFMT_H
+
+#include "version.h"
+
+enum AVSubtitleType {
+
+/**
+ * Subtitle format unknown.
+ */
+AV_SUBTITLE_FMT_NONE = -1,
+
+/**
+ * Subtitle format unknown.
+ */
+AV_SUBTITLE_FMT_UNKNOWN = 0,
+#if FF_API_OLD_SUBTITLES
+SUBTITLE_NONE = 0,  ///< Deprecated, use AV_SUBTITLE_FMT_NONE 
instead.
+#endif
+
+/**
+ * Bitmap area in AVSubtitleRect.data, pixfmt AV_PIX_FMT_PAL8.
+ */
+AV_SUBTITLE_FMT_BITMAP = 1,
+#if FF_API_OLD_SUBTITLES
+SUBTITLE_BITMAP = 1,///< Deprecated, use AV_SUBTITLE_FMT_BITMAP 
instead.
+#endif
+
+/**
+ * Plain text in AVSubtitleRect.text.
+ */
+AV_SUBTITLE_FMT_TEXT = 2,
+#if FF_API_OLD_SUBTITLES
+SUBTITLE_TEXT = 2,  ///< Deprecated, use AV_SUBTITLE_FMT_TEXT 
instead.
+#endif
+
+/**
+ * Text Formatted as per ASS specification, contained AVSubtitleRect.ass.
+ */
+AV_SUBTITLE_FMT_ASS = 3,
+#if FF_API_OLD_SUBTITLES
+SUBTITLE_ASS = 3,   ///< Deprecated, use AV_SUBTITLE_FMT_ASS 
instead.
+#endif
+
+AV_SUBTITLE_FMT_NB, ///< number of subtitle formats, DO NOT USE 
THIS if you want to link with shared libav* because the number of formats might 
differ between versions.
+};
+
+#endif /* AVUTIL_SUBFMT_H */
diff --git a/libavutil/version.h b/libavutil/version.h
index 953aac9d94..5bf48f6304 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -110,6 +110,7 @@
 #define FF_API_COLORSPACE_NAME  (LIBAVUTIL_VERSION_MAJOR < 58)
 #define FF_API_AV_MALLOCZ_ARRAY (LIBAVUTIL_VERSION_MAJOR < 58)
 #define FF_API_FIFO_PEEK2   (LIBAVUTIL_VERSION_MAJOR < 58)
+#define FF_API_OLD_SUBTITLES(LIBAVUTIL_VERSION_MAJOR < 58)
 
 /**
  * @}
-- 
ffmpeg-codebot

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or ema

[FFmpeg-devel] [PATCH v3 02/26] avutil/frame: Prepare AVFrame for subtitle handling

2022-01-19 Thread ffmpegagent
From: softworkz 

Root commit for adding subtitle filtering capabilities.
In detail:

- Add type (AVMediaType) field to AVFrame
  Replaces previous way of distinction which was based on checking
  width and height to determine whether a frame is audio or video
- Add subtitle fields to AVFrame
- Add new struct AVSubtitleArea, similar to AVSubtitleRect, but
  different allocation logic. Cannot and must not be used
  interchangeably, hence the new struct

Signed-off-by: softworkz 
---
 libavutil/Makefile |   1 +
 libavutil/frame.c  | 211 -
 libavutil/frame.h  |  85 +-
 libavutil/subfmt.c |  45 ++
 libavutil/subfmt.h |  47 ++
 5 files changed, 364 insertions(+), 25 deletions(-)
 create mode 100644 libavutil/subfmt.c

diff --git a/libavutil/Makefile b/libavutil/Makefile
index ce644f4d48..8bc0a14942 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -160,6 +160,7 @@ OBJS = adler32.o
\
slicethread.o\
spherical.o  \
stereo3d.o   \
+   subfmt.o \
threadmessage.o  \
time.o   \
timecode.o   \
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 8997c85e35..2b95830b6f 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -26,6 +26,7 @@
 #include "imgutils.h"
 #include "mem.h"
 #include "samplefmt.h"
+#include "subfmt.h"
 #include "hwcontext.h"
 
 #define CHECK_CHANNELS_CONSISTENCY(frame) \
@@ -50,6 +51,9 @@ const char *av_get_colorspace_name(enum AVColorSpace val)
 return name[val];
 }
 #endif
+
+static int frame_copy_subtitles(AVFrame *dst, const AVFrame *src, int 
copy_data);
+
 static void get_frame_defaults(AVFrame *frame)
 {
 memset(frame, 0, sizeof(*frame));
@@ -70,7 +74,12 @@ static void get_frame_defaults(AVFrame *frame)
 frame->colorspace  = AVCOL_SPC_UNSPECIFIED;
 frame->color_range = AVCOL_RANGE_UNSPECIFIED;
 frame->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
-frame->flags   = 0;
+frame->num_subtitle_areas  = 0;
+frame->subtitle_areas  = NULL;
+frame->subtitle_header = NULL;
+frame->repeat_sub  = 0;
+frame->subtitle_timing.start_pts = 0;
+frame->subtitle_timing.duration  = 0;
 }
 
 static void free_side_data(AVFrameSideData **ptr_sd)
@@ -240,23 +249,55 @@ static int get_audio_buffer(AVFrame *frame, int align)
 
 }
 
+static int get_subtitle_buffer(AVFrame *frame)
+{
+// Buffers in AVFrame->buf[] are not used in case of subtitle frames.
+// To accomodate with existing code, checking ->buf[0] to determine
+// whether a frame is ref-counted or has data, we're adding a 1-byte
+// buffer here, which marks the subtitle frame to contain data.
+frame->buf[0] = av_buffer_alloc(1);
+if (!frame->buf[0]) {
+av_frame_unref(frame);
+return AVERROR(ENOMEM);
+}
+
+frame->extended_data = frame->data;
+
+return 0;
+}
+
 int av_frame_get_buffer(AVFrame *frame, int align)
+{
+if (frame->width > 0 && frame->height > 0)
+frame->type = AVMEDIA_TYPE_VIDEO;
+else if (frame->nb_samples > 0 && (frame->channel_layout || 
frame->channels > 0))
+frame->type = AVMEDIA_TYPE_AUDIO;
+
+return av_frame_get_buffer2(frame, align);
+}
+
+int av_frame_get_buffer2(AVFrame *frame, int align)
 {
 if (frame->format < 0)
 return AVERROR(EINVAL);
 
-if (frame->width > 0 && frame->height > 0)
+switch(frame->type) {
+case AVMEDIA_TYPE_VIDEO:
 return get_video_buffer(frame, align);
-else if (frame->nb_samples > 0 && (frame->channel_layout || 
frame->channels > 0))
+case AVMEDIA_TYPE_AUDIO:
 return get_audio_buffer(frame, align);
-
-return AVERROR(EINVAL);
+case AVMEDIA_TYPE_SUBTITLE:
+return get_subtitle_buffer(frame);
+default:
+return AVERROR(EINVAL);
+}
 }
 
 static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy)
 {
 int ret, i;
 
+dst->type   = src->type;
 dst->key_frame  = src->key_frame;
 dst->pict_type  = src->pict_type;
 dst->sample_aspect_ratio= src->sample_aspect_ratio;
@@ -288,6 +329,12 @@ static int frame_copy_props(AVFrame *dst, const AVFrame 
*src, int force_copy)
 dst->colorspace = src->colorspace;
 dst->color_range= src->color_range;
 dst->chroma_location= src->chroma_location;
+dst->repeat_sub = src->repeat_sub;
+dst->subtitle_timing.start_pts = src->subtitle_timing.start_pts;
+  

[FFmpeg-devel] [PATCH v3 03/26] avcodec/subtitles: Introduce new frame-based subtitle decoding API

2022-01-19 Thread ffmpegagent
From: softworkz 

- Modify avcodec_send_packet() to support subtitles via the regular
  frame based decoding API
- Add decode_subtitle_shim() which takes subtitle frames,
  and serves as a compatibility shim to the legacy subtitle decoding
  API until all subtitle decoders are migrated to the frame-based API
- Add additional methods for conversion between old and new API

Signed-off-by: softworkz 
---
 libavcodec/avcodec.h|   8 +-
 libavcodec/codec_desc.c |  11 +++
 libavcodec/codec_desc.h |   8 ++
 libavcodec/decode.c |  60 +++--
 libavcodec/internal.h   |  16 
 libavcodec/utils.c  | 184 
 6 files changed, 278 insertions(+), 9 deletions(-)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index fe5a83cf85..9d59f6e840 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1675,7 +1675,7 @@ typedef struct AVCodecContext {
 
 /**
  * Header containing style information for text subtitles.
- * For SUBTITLE_ASS subtitle type, it should contain the whole ASS
+ * For AV_SUBTITLE_FMT_ASS subtitle type, it should contain the whole ASS
  * [Script Info] and [V4+ Styles] section, plus the [Events] line and
  * the Format line following. It shouldn't include any Dialogue line.
  * - encoding: Set/allocated/freed by user (before avcodec_open2())
@@ -2415,7 +2415,10 @@ int avcodec_close(AVCodecContext *avctx);
  * Free all allocated data in the given subtitle struct.
  *
  * @param sub AVSubtitle to free.
+ *
+ * @deprecated Use the regular frame based encode and decode APIs instead.
  */
+attribute_deprecated
 void avsubtitle_free(AVSubtitle *sub);
 
 /**
@@ -2508,7 +2511,10 @@ enum AVChromaLocation avcodec_chroma_pos_to_enum(int 
xpos, int ypos);
  * must be freed with avsubtitle_free if *got_sub_ptr is set.
  * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, 
otherwise, it is nonzero.
  * @param[in] avpkt The input AVPacket containing the input buffer.
+ *
+ * @deprecated Use the new decode API (avcodec_send_packet, 
avcodec_receive_frame) instead.
  */
+attribute_deprecated
 int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
 int *got_sub_ptr,
 AVPacket *avpkt);
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 0974ee03de..e48e4532ba 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -3548,3 +3548,14 @@ enum AVMediaType avcodec_get_type(enum AVCodecID 
codec_id)
 const AVCodecDescriptor *desc = avcodec_descriptor_get(codec_id);
 return desc ? desc->type : AVMEDIA_TYPE_UNKNOWN;
 }
+
+enum AVSubtitleType avcodec_descriptor_get_subtitle_format(const 
AVCodecDescriptor *codec_descriptor)
+{
+if(codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB)
+return AV_SUBTITLE_FMT_BITMAP;
+
+if(codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB)
+return AV_SUBTITLE_FMT_ASS;
+
+return AV_SUBTITLE_FMT_UNKNOWN;
+}
diff --git a/libavcodec/codec_desc.h b/libavcodec/codec_desc.h
index 126b52df47..ba68d24e0e 100644
--- a/libavcodec/codec_desc.h
+++ b/libavcodec/codec_desc.h
@@ -121,6 +121,14 @@ const AVCodecDescriptor *avcodec_descriptor_next(const 
AVCodecDescriptor *prev);
  */
 const AVCodecDescriptor *avcodec_descriptor_get_by_name(const char *name);
 
+/**
+ * Return subtitle format from a codec descriptor
+ *
+ * @param codec_descriptor codec descriptor
+ * @return the subtitle type (e.g. bitmap, text)
+ */
+enum AVSubtitleType avcodec_descriptor_get_subtitle_format(const 
AVCodecDescriptor *codec_descriptor);
+
 /**
  * @}
  */
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 0912f86a14..e3cf1cfa3d 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -576,6 +576,39 @@ static int decode_receive_frame_internal(AVCodecContext 
*avctx, AVFrame *frame)
 return ret;
 }
 
+static int decode_subtitle2_priv(AVCodecContext *avctx, AVSubtitle *sub,
+ int *got_sub_ptr, AVPacket *avpkt);
+
+static int decode_subtitle_shim(AVCodecContext *avctx, AVFrame *frame, 
AVPacket *avpkt)
+{
+int ret, got_sub_ptr = 0;
+AVSubtitle subtitle = { 0 };
+
+if (frame->buf[0])
+return AVERROR(EAGAIN);
+
+av_frame_unref(frame);
+
+ret = decode_subtitle2_priv(avctx, &subtitle, &got_sub_ptr, avpkt);
+
+if (ret >= 0 && got_sub_ptr) {
+frame->type = AVMEDIA_TYPE_SUBTITLE;
+frame->format = subtitle.format;
+ret = av_frame_get_buffer2(frame, 0);
+
+if (ret >= 0)
+ret = ff_frame_put_subtitle(frame, &subtitle);
+
+frame->width = avctx->width;
+frame->height = avctx->height;
+frame->pkt_dts = avpkt->dts;
+}
+
+avsubtitle_free(&subtitle);
+
+return ret;
+}
+
 int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const 
AVPacket *avpkt)
 {
 AVCodecInternal *avci = avctx->internal;
@@ -59

[FFmpeg-devel] [PATCH v3 09/26] avfilter/avfilter: Handle subtitle frames

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/avfilter.c  |  8 +---
 libavfilter/avfilter.h  | 11 +++
 libavfilter/avfiltergraph.c |  5 +
 libavfilter/formats.c   | 22 ++
 libavfilter/formats.h   |  3 +++
 libavfilter/internal.h  | 18 +++---
 6 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index df5b8f483c..75d5e86539 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -56,7 +56,8 @@ static void tlog_ref(void *ctx, AVFrame *ref, int end)
 ref->linesize[0], ref->linesize[1], ref->linesize[2], 
ref->linesize[3],
 ref->pts, ref->pkt_pos);
 
-if (ref->width) {
+switch(ref->type) {
+case AVMEDIA_TYPE_VIDEO:
 ff_tlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c",
 ref->sample_aspect_ratio.num, ref->sample_aspect_ratio.den,
 ref->width, ref->height,
@@ -64,12 +65,13 @@ static void tlog_ref(void *ctx, AVFrame *ref, int end)
 ref->top_field_first ? 'T' : 'B',/* Top / Bottom */
 ref->key_frame,
 av_get_picture_type_char(ref->pict_type));
-}
-if (ref->nb_samples) {
+break;
+case AVMEDIA_TYPE_AUDIO:
 ff_tlog(ctx, " cl:%"PRId64"d n:%d r:%d",
 ref->channel_layout,
 ref->nb_samples,
 ref->sample_rate);
+break;
 }
 
 ff_tlog(ctx, "]%s", end ? "\n" : "");
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index b105dc3159..9f917deb41 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -45,6 +45,7 @@
 #include "libavutil/log.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/pixfmt.h"
+#include "libavutil/subfmt.h"
 #include "libavutil/rational.h"
 
 #include "libavfilter/version.h"
@@ -343,6 +344,12 @@ typedef struct AVFilter {
  * and outputs use the same sample rate and channel count/layout.
  */
 const enum AVSampleFormat *samples_list;
+/**
+ * Analogous to pixels, but delimited by AV_SUBTITLE_FMT_NONE
+ * and restricted to filters that only have AVMEDIA_TYPE_SUBTITLE
+ * inputs and outputs.
+ */
+const enum AVSubtitleType *subs_list;
 /**
  * Equivalent to { pix_fmt, AV_PIX_FMT_NONE } as pixels_list.
  */
@@ -351,6 +358,10 @@ typedef struct AVFilter {
  * Equivalent to { sample_fmt, AV_SAMPLE_FMT_NONE } as samples_list.
  */
 enum AVSampleFormat sample_fmt;
+/**
+ * Equivalent to { sub_fmt, AV_SUBTITLE_FMT_NONE } as subs_list.
+ */
+enum AVSubtitleType sub_fmt;
 } formats;
 
 int priv_size;  ///< size of private data to allocate for the filter
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index b8b432e98b..f4987654af 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -311,6 +311,8 @@ static int filter_link_check_formats(void *log, 
AVFilterLink *link, AVFilterForm
 return ret;
 break;
 
+case AVMEDIA_TYPE_SUBTITLE:
+return 0;
 default:
 av_assert0(!"reached");
 }
@@ -441,6 +443,9 @@ static int query_formats(AVFilterGraph *graph, void 
*log_ctx)
 if (!link)
 continue;
 
+if (link->type == AVMEDIA_TYPE_SUBTITLE)
+continue;
+
 neg = ff_filter_get_negotiation(link);
 av_assert0(neg);
 for (neg_step = 1; neg_step < neg->nb_mergers; neg_step++) {
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index ba62f73248..5c972bb183 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/subfmt.h"
 #include "libavutil/avassert.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
@@ -431,6 +432,12 @@ int ff_add_channel_layout(AVFilterChannelLayouts **l, 
uint64_t channel_layout)
 return 0;
 }
 
+int ff_add_subtitle_type(AVFilterFormats **avff, int64_t fmt)
+{
+ADD_FORMAT(avff, fmt, ff_formats_unref, int, formats, nb_formats);
+return 0;
+}
+
 AVFilterFormats *ff_make_formats_list_singleton(int fmt)
 {
 int fmts[2] = { fmt, -1 };
@@ -450,6 +457,13 @@ AVFilterFormats *ff_all_formats(enum AVMediaType type)
 return NULL;
 fmt++;
 }
+} else if (type == AVMEDIA_TYPE_SUBTITLE) {
+if (ff_add_subtitle_type(&ret, AV_SUBTITLE_FMT_BITMAP) < 0)
+return NULL;
+if (ff_add_subtitle_type(&ret, AV_SUBTITLE_FMT_ASS) < 0)
+return NULL;
+if (ff_add_subtitle_type(&ret, AV_SUBTITLE_FMT_TEXT) < 0)
+return NULL;
 }
 
 return ret;
@@ -724,6 +738,10 @@ int ff_default_query_formats(AVFilterContext *ctx)
 type= 

[FFmpeg-devel] [PATCH v3 04/26] avfilter/subtitles: Update vf_subtitles to use new decoding api

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_subtitles.c | 56 +-
 1 file changed, 43 insertions(+), 13 deletions(-)

diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c
index 3fc4eeb63d..25e217e845 100644
--- a/libavfilter/vf_subtitles.c
+++ b/libavfilter/vf_subtitles.c
@@ -35,14 +35,12 @@
 # include "libavformat/avformat.h"
 #endif
 #include "libavutil/avstring.h"
-#include "libavutil/imgutils.h"
 #include "libavutil/opt.h"
 #include "libavutil/parseutils.h"
 #include "drawutils.h"
 #include "avfilter.h"
 #include "internal.h"
 #include "formats.h"
-#include "video.h"
 
 typedef struct AssContext {
 const AVClass *class;
@@ -292,6 +290,29 @@ static int attachment_is_font(AVStream * st)
 return 0;
 }
 
+static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, 
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)
+*got_frame = 1;
+
+return 0;
+}
+
 AVFILTER_DEFINE_CLASS(subtitles);
 
 static av_cold int init_subtitles(AVFilterContext *ctx)
@@ -306,6 +327,7 @@ static av_cold int init_subtitles(AVFilterContext *ctx)
 AVStream *st;
 AVPacket pkt;
 AssContext *ass = ctx->priv;
+enum AVSubtitleType subtitle_format;
 
 /* Init libass */
 ret = init(ctx);
@@ -386,13 +408,17 @@ static av_cold int init_subtitles(AVFilterContext *ctx)
 ret = AVERROR_DECODER_NOT_FOUND;
 goto end;
 }
+
 dec_desc = avcodec_descriptor_get(st->codecpar->codec_id);
-if (dec_desc && !(dec_desc->props & AV_CODEC_PROP_TEXT_SUB)) {
+subtitle_format = avcodec_descriptor_get_subtitle_format(dec_desc);
+
+if (subtitle_format != AV_SUBTITLE_FMT_ASS) {
 av_log(ctx, AV_LOG_ERROR,
-   "Only text based subtitles are currently supported\n");
-ret = AVERROR_PATCHWELCOME;
+   "Only text based subtitles are supported by this filter\n");
+ret = AVERROR_INVALIDDATA;
 goto end;
 }
+
 if (ass->charenc)
 av_dict_set(&codec_opts, "sub_charenc", ass->charenc, 0);
 
@@ -448,27 +474,31 @@ static av_cold int init_subtitles(AVFilterContext *ctx)
   dec_ctx->subtitle_header_size);
 while (av_read_frame(fmt, &pkt) >= 0) {
 int i, got_subtitle;
-AVSubtitle sub = {0};
+AVFrame *sub = av_frame_alloc();
+if (!sub) {
+ret = AVERROR(ENOMEM);
+goto end;
+}
 
 if (pkt.stream_index == sid) {
-ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_subtitle, &pkt);
+ret = decode(dec_ctx, sub, &got_subtitle, &pkt);
 if (ret < 0) {
 av_log(ctx, AV_LOG_WARNING, "Error decoding: %s (ignored)\n",
av_err2str(ret));
 } else if (got_subtitle) {
-const int64_t start_time = av_rescale_q(sub.pts, 
AV_TIME_BASE_Q, av_make_q(1, 1000));
-const int64_t duration   = sub.end_display_time;
-for (i = 0; i < sub.num_rects; i++) {
-char *ass_line = sub.rects[i]->ass;
+const int64_t start_time = 
av_rescale_q(sub->subtitle_timing.start_pts, AV_TIME_BASE_Q, av_make_q(1, 
1000));
+const int64_t duration   = 
av_rescale_q(sub->subtitle_timing.duration, AV_TIME_BASE_Q, av_make_q(1, 1000));
+for (i = 0; i < sub->num_subtitle_areas; i++) {
+char *ass_line = sub->subtitle_areas[i]->ass;
 if (!ass_line)
-break;
+continue;
 ass_process_chunk(ass->track, ass_line, strlen(ass_line),
   start_time, duration);
 }
 }
 }
 av_packet_unref(&pkt);
-avsubtitle_free(&sub);
+av_frame_free(&sub);
 }
 
 end:
-- 
ffmpeg-codebot

___
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 v3 10/26] avfilter/avfilter: Fix hardcoded input index

2022-01-19 Thread ffmpegagent
From: softworkz 

This fix targets (rare) cases where multiple input pads have a
.filter_frame function. ff_request_frame_to_filter needs
to call ff_request_frame with the correct input pad
instead of the hardcoded first one.

Signed-off-by: softworkz 
---
 libavfilter/avfilter.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 75d5e86539..aa9aa71f53 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -463,7 +463,7 @@ static int64_t guess_status_pts(AVFilterContext *ctx, int 
status, AVRational lin
 return AV_NOPTS_VALUE;
 }
 
-static int ff_request_frame_to_filter(AVFilterLink *link)
+static int ff_request_frame_to_filter(AVFilterLink *link, int input_index)
 {
 int ret = -1;
 
@@ -472,8 +472,8 @@ static int ff_request_frame_to_filter(AVFilterLink *link)
 link->frame_blocked_in = 1;
 if (link->srcpad->request_frame)
 ret = link->srcpad->request_frame(link);
-else if (link->src->inputs[0])
-ret = ff_request_frame(link->src->inputs[0]);
+else if (link->src->inputs[input_index])
+ret = ff_request_frame(link->src->inputs[input_index]);
 if (ret < 0) {
 if (ret != AVERROR(EAGAIN) && ret != link->status_in)
 ff_avfilter_link_set_in_status(link, ret, 
guess_status_pts(link->src, ret, link->time_base));
@@ -1172,6 +1172,14 @@ static int forward_status_change(AVFilterContext 
*filter, AVFilterLink *in)
 {
 unsigned out = 0, progress = 0;
 int ret;
+int input_index = 0;
+
+for (int i = 0; i < in->dst->nb_inputs; i++) {
+if (&in->dst->input_pads[i] == in->dstpad) {
+input_index = i;
+break;
+}
+}
 
 av_assert0(!in->status_out);
 if (!filter->nb_outputs) {
@@ -1181,7 +1189,7 @@ static int forward_status_change(AVFilterContext *filter, 
AVFilterLink *in)
 while (!in->status_out) {
 if (!filter->outputs[out]->status_in) {
 progress++;
-ret = ff_request_frame_to_filter(filter->outputs[out]);
+ret = ff_request_frame_to_filter(filter->outputs[out], 
input_index);
 if (ret < 0)
 return ret;
 }
@@ -1218,7 +1226,7 @@ static int ff_filter_activate_default(AVFilterContext 
*filter)
 for (i = 0; i < filter->nb_outputs; i++) {
 if (filter->outputs[i]->frame_wanted_out &&
 !filter->outputs[i]->frame_blocked_in) {
-return ff_request_frame_to_filter(filter->outputs[i]);
+return ff_request_frame_to_filter(filter->outputs[i], 0);
 }
 }
 return FFERROR_NOT_READY;
-- 
ffmpeg-codebot

___
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 v3 05/26] avcodec, avutil: Move ass helper functions to avutil as avpriv_ and extend ass dialog parsing

2022-01-19 Thread ffmpegagent
From: softworkz 

Also add

- hard_space callback (for upcoming fix)
- extensible callback (for future extension)

Signed-off-by: softworkz 
---
 libavcodec/Makefile   |  56 +++
 libavcodec/ass.h  | 144 ++
 libavcodec/assdec.c   |   2 +-
 libavcodec/assenc.c   |   2 +-
 libavcodec/ccaption_dec.c |  19 +--
 libavcodec/jacosubdec.c   |   2 +-
 libavcodec/libaribb24.c   |   2 +-
 libavcodec/libzvbi-teletextdec.c  |  14 +-
 libavcodec/microdvddec.c  |   7 +-
 libavcodec/movtextdec.c   |   3 +-
 libavcodec/movtextenc.c   |  20 +--
 libavcodec/mpl2dec.c  |   2 +-
 libavcodec/realtextdec.c  |   2 +-
 libavcodec/samidec.c  |   2 +-
 libavcodec/srtdec.c   |   2 +-
 libavcodec/srtenc.c   |  16 +-
 libavcodec/subviewerdec.c |   2 +-
 libavcodec/textdec.c  |   4 +-
 libavcodec/ttmlenc.c  |  15 +-
 libavcodec/webvttdec.c|   2 +-
 libavcodec/webvttenc.c|  16 +-
 libavutil/Makefile|   2 +
 {libavcodec => libavutil}/ass.c   |  91 +--
 libavutil/ass_internal.h  | 135 
 {libavcodec => libavutil}/ass_split.c |  30 ++--
 .../ass_split_internal.h  |  32 ++--
 26 files changed, 355 insertions(+), 269 deletions(-)
 rename {libavcodec => libavutil}/ass.c (65%)
 create mode 100644 libavutil/ass_internal.h
 rename {libavcodec => libavutil}/ass_split.c (94%)
 rename libavcodec/ass_split.h => libavutil/ass_split_internal.h (86%)

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index cfc70a3eaf..80bf8ff2d2 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -215,10 +215,10 @@ OBJS-$(CONFIG_APNG_DECODER)+= png.o pngdec.o 
pngdsp.o
 OBJS-$(CONFIG_APNG_ENCODER)+= png.o pngenc.o
 OBJS-$(CONFIG_ARBC_DECODER)+= arbc.o
 OBJS-$(CONFIG_ARGO_DECODER)+= argo.o
-OBJS-$(CONFIG_SSA_DECODER) += assdec.o ass.o
-OBJS-$(CONFIG_SSA_ENCODER) += assenc.o ass.o
-OBJS-$(CONFIG_ASS_DECODER) += assdec.o ass.o
-OBJS-$(CONFIG_ASS_ENCODER) += assenc.o ass.o
+OBJS-$(CONFIG_SSA_DECODER) += assdec.o
+OBJS-$(CONFIG_SSA_ENCODER) += assenc.o
+OBJS-$(CONFIG_ASS_DECODER) += assdec.o
+OBJS-$(CONFIG_ASS_ENCODER) += assenc.o
 OBJS-$(CONFIG_ASV1_DECODER)+= asvdec.o asv.o mpeg12data.o
 OBJS-$(CONFIG_ASV1_ENCODER)+= asvenc.o asv.o mpeg12data.o
 OBJS-$(CONFIG_ASV2_DECODER)+= asvdec.o asv.o mpeg12data.o
@@ -259,7 +259,7 @@ OBJS-$(CONFIG_BRENDER_PIX_DECODER) += brenderpix.o
 OBJS-$(CONFIG_C93_DECODER) += c93.o
 OBJS-$(CONFIG_CAVS_DECODER)+= cavs.o cavsdec.o cavsdsp.o \
   cavsdata.o
-OBJS-$(CONFIG_CCAPTION_DECODER)+= ccaption_dec.o ass.o
+OBJS-$(CONFIG_CCAPTION_DECODER)+= ccaption_dec.o
 OBJS-$(CONFIG_CDGRAPHICS_DECODER)  += cdgraphics.o
 OBJS-$(CONFIG_CDTOONS_DECODER) += cdtoons.o
 OBJS-$(CONFIG_CDXL_DECODER)+= cdxl.o
@@ -434,7 +434,7 @@ OBJS-$(CONFIG_INTERPLAY_ACM_DECODER)   += interplayacm.o
 OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER)  += dpcm.o
 OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o
 OBJS-$(CONFIG_IPU_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o
-OBJS-$(CONFIG_JACOSUB_DECODER) += jacosubdec.o ass.o
+OBJS-$(CONFIG_JACOSUB_DECODER) += jacosubdec.o
 OBJS-$(CONFIG_JPEG2000_ENCODER)+= j2kenc.o mqcenc.o mqc.o jpeg2000.o \
   jpeg2000dwt.o
 OBJS-$(CONFIG_JPEG2000_DECODER)+= jpeg2000dec.o jpeg2000.o 
jpeg2000dsp.o \
@@ -456,7 +456,7 @@ OBJS-$(CONFIG_MAGICYUV_ENCODER)+= magicyuvenc.o
 OBJS-$(CONFIG_MDEC_DECODER)+= mdec.o mpeg12.o mpeg12data.o
 OBJS-$(CONFIG_METASOUND_DECODER)   += metasound.o metasound_data.o \
   twinvq.o
-OBJS-$(CONFIG_MICRODVD_DECODER)+= microdvddec.o ass.o
+OBJS-$(CONFIG_MICRODVD_DECODER)+= microdvddec.o
 OBJS-$(CONFIG_MIMIC_DECODER)   += mimic.o
 OBJS-$(CONFIG_MJPEG_DECODER)   += mjpegdec.o mjpegdec_common.o
 OBJS-$(CONFIG_MJPEG_QSV_DECODER)   += qsvdec.o
@@ -471,8 +471,8 @@ OBJS-$(CONFIG_MLP_ENCODER) += mlpenc.o mlp.o
 OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o
 OBJS-$(CONFIG_MOBICLIP_DECODER)+= mobiclip.o
 OBJS-$(CONFIG_MOTIONPIXELS_DECODER)+= motionpixels.o
-OBJS-$(CONFIG_MOVTEXT_DECODER) += movtextdec.o ass.o
-OBJS-$(CONFIG_MOVTEXT_ENCOD

[FFmpeg-devel] [PATCH v3 06/26] avcodec/subtitles: Replace deprecated enum values

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/ass.h   | 2 +-
 libavcodec/assdec.c| 2 +-
 libavcodec/dvbsubdec.c | 2 +-
 libavcodec/dvdsubdec.c | 2 +-
 libavcodec/dvdsubenc.c | 2 +-
 libavcodec/pgssubdec.c | 2 +-
 libavcodec/xsubdec.c   | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/libavcodec/ass.h b/libavcodec/ass.h
index 8bc13d7ab8..43c5ad651a 100644
--- a/libavcodec/ass.h
+++ b/libavcodec/ass.h
@@ -83,7 +83,7 @@ static inline int avpriv_ass_add_rect(AVSubtitle *sub, const 
char *dialog,
 rects[sub->num_rects]   = av_mallocz(sizeof(*rects[0]));
 if (!rects[sub->num_rects])
 return AVERROR(ENOMEM);
-rects[sub->num_rects]->type = SUBTITLE_ASS;
+rects[sub->num_rects]->type = AV_SUBTITLE_FMT_ASS;
 ass_str = avpriv_ass_get_dialog(readorder, layer, style, speaker, dialog);
 if (!ass_str)
 return AVERROR(ENOMEM);
diff --git a/libavcodec/assdec.c b/libavcodec/assdec.c
index 7802a44e71..fd321e7004 100644
--- a/libavcodec/assdec.c
+++ b/libavcodec/assdec.c
@@ -54,7 +54,7 @@ static int ass_decode_frame(AVCodecContext *avctx, void 
*data, int *got_sub_ptr,
 if (!sub->rects[0])
 return AVERROR(ENOMEM);
 sub->num_rects = 1;
-sub->rects[0]->type = SUBTITLE_ASS;
+sub->rects[0]->type = AV_SUBTITLE_FMT_ASS;
 sub->rects[0]->ass  = av_strdup(avpkt->data);
 if (!sub->rects[0]->ass)
 return AVERROR(ENOMEM);
diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c
index bc741a1de6..0d64c6e71c 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -795,7 +795,7 @@ static int save_subtitle_set(AVCodecContext *avctx, 
AVSubtitle *sub, int *got_ou
 rect->w = region->width;
 rect->h = region->height;
 rect->nb_colors = (1 << region->depth);
-rect->type  = SUBTITLE_BITMAP;
+rect->type  = AV_SUBTITLE_FMT_BITMAP;
 rect->linesize[0] = region->width;
 
 clut = get_clut(ctx, region->clut);
diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c
index 52259f0730..b39b3d1838 100644
--- a/libavcodec/dvdsubdec.c
+++ b/libavcodec/dvdsubdec.c
@@ -406,7 +406,7 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, 
AVSubtitle *sub_header,
 sub_header->rects[0]->y = y1;
 sub_header->rects[0]->w = w;
 sub_header->rects[0]->h = h;
-sub_header->rects[0]->type = SUBTITLE_BITMAP;
+sub_header->rects[0]->type = AV_SUBTITLE_FMT_BITMAP;
 sub_header->rects[0]->linesize[0] = w;
 sub_header->rects[0]->flags = is_menu ? 
AV_SUBTITLE_FLAG_FORCED : 0;
 }
diff --git a/libavcodec/dvdsubenc.c b/libavcodec/dvdsubenc.c
index ff4fbed39d..943a7466d9 100644
--- a/libavcodec/dvdsubenc.c
+++ b/libavcodec/dvdsubenc.c
@@ -268,7 +268,7 @@ static int encode_dvd_subtitles(AVCodecContext *avctx,
 if (rects == 0 || !h->rects)
 return AVERROR(EINVAL);
 for (i = 0; i < rects; i++)
-if (h->rects[i]->type != SUBTITLE_BITMAP) {
+if (h->rects[i]->type != AV_SUBTITLE_FMT_BITMAP) {
 av_log(avctx, AV_LOG_ERROR, "Bitmap subtitle required\n");
 return AVERROR(EINVAL);
 }
diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c
index bdd20c914b..22b6616f9b 100644
--- a/libavcodec/pgssubdec.c
+++ b/libavcodec/pgssubdec.c
@@ -535,7 +535,7 @@ static int display_end_segment(AVCodecContext *avctx, void 
*data,
 if (!rect)
 return AVERROR(ENOMEM);
 sub->rects[sub->num_rects++] = rect;
-rect->type = SUBTITLE_BITMAP;
+rect->type = AV_SUBTITLE_FMT_BITMAP;
 
 /* Process bitmap */
 object = find_object(ctx->presentation.objects[i].id, &ctx->objects);
diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c
index 85cd7d1c20..a4be18a1d8 100644
--- a/libavcodec/xsubdec.c
+++ b/libavcodec/xsubdec.c
@@ -107,7 +107,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, 
int *got_sub_ptr,
 sub->num_rects = 1;
 rect->x = x; rect->y = y;
 rect->w = w; rect->h = h;
-rect->type = SUBTITLE_BITMAP;
+rect->type = AV_SUBTITLE_FMT_BITMAP;
 rect->linesize[0] = w;
 rect->data[0] = av_malloc(w * h);
 rect->nb_colors = 4;
-- 
ffmpeg-codebot

___
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 v3 11/26] avfilter/sbuffer: Add sbuffersrc and sbuffersink filters

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 configure|  2 +-
 libavfilter/allfilters.c |  2 ++
 libavfilter/buffersink.c | 54 ++
 libavfilter/buffersink.h |  7 
 libavfilter/buffersrc.c  | 72 
 libavfilter/buffersrc.h  |  1 +
 6 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 52ef214b73..1928a77344 100755
--- a/configure
+++ b/configure
@@ -7856,7 +7856,7 @@ print_enabled_components(){
 fi
 done
 if [ "$name" = "filter_list" ]; then
-for c in asrc_abuffer vsrc_buffer asink_abuffer vsink_buffer; do
+for c in asrc_abuffer vsrc_buffer ssrc_sbuffer asink_abuffer 
vsink_buffer ssink_sbuffer; do
 printf "&ff_%s,\n" $c >> $TMPH
 done
 fi
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 714468afce..ebb2e374bd 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -557,8 +557,10 @@ extern const AVFilter ff_avsrc_movie;
  * being the same while having different 'types'). */
 extern  const AVFilter ff_asrc_abuffer;
 extern  const AVFilter ff_vsrc_buffer;
+extern  const AVFilter ff_ssrc_sbuffer;
 extern  const AVFilter ff_asink_abuffer;
 extern  const AVFilter ff_vsink_buffer;
+extern  const AVFilter ff_ssink_sbuffer;
 extern const AVFilter ff_af_afifo;
 extern const AVFilter ff_vf_fifo;
 
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
index c0215669e7..0b268c2fa4 100644
--- a/libavfilter/buffersink.c
+++ b/libavfilter/buffersink.c
@@ -29,6 +29,8 @@
 #include "libavutil/internal.h"
 #include "libavutil/opt.h"
 
+#include "libavcodec/avcodec.h"
+
 #define FF_INTERNAL_FIELDS 1
 #include "framequeue.h"
 
@@ -57,6 +59,10 @@ typedef struct BufferSinkContext {
 int *sample_rates;  ///< list of accepted sample rates
 int sample_rates_size;
 
+/* only used for subtitles */
+enum AVSubtitleType *subtitle_types; ///< list of accepted subtitle 
types, must be terminated with -1
+int subtitle_types_size;
+
 AVFrame *peeked_frame;
 } BufferSinkContext;
 
@@ -305,6 +311,28 @@ static int asink_query_formats(AVFilterContext *ctx)
 return 0;
 }
 
+static int ssink_query_formats(AVFilterContext *ctx)
+{
+BufferSinkContext *buf = ctx->priv;
+AVFilterFormats *formats = NULL;
+unsigned i;
+int ret;
+
+CHECK_LIST_SIZE(subtitle_types)
+if (buf->subtitle_types_size) {
+for (i = 0; i < NB_ITEMS(buf->subtitle_types); i++)
+if ((ret = ff_add_subtitle_type(&formats, buf->subtitle_types[i])) 
< 0)
+return ret;
+if ((ret = ff_set_common_formats(ctx, formats)) < 0)
+return ret;
+} else {
+if ((ret = ff_default_query_formats(ctx)) < 0)
+return ret;
+}
+
+return 0;
+}
+
 #define OFFSET(x) offsetof(BufferSinkContext, x)
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 static const AVOption buffersink_options[] = {
@@ -322,9 +350,16 @@ static const AVOption abuffersink_options[] = {
 { NULL },
 };
 #undef FLAGS
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_SUBTITLE_PARAM
+static const AVOption sbuffersink_options[] = {
+{ "subtitle_types", "set the supported subtitle formats", 
OFFSET(subtitle_types), AV_OPT_TYPE_BINARY, .flags = FLAGS },
+{ NULL },
+};
+#undef FLAGS
 
 AVFILTER_DEFINE_CLASS(buffersink);
 AVFILTER_DEFINE_CLASS(abuffersink);
+AVFILTER_DEFINE_CLASS(sbuffersink);
 
 static const AVFilterPad avfilter_vsink_buffer_inputs[] = {
 {
@@ -363,3 +398,22 @@ const AVFilter ff_asink_abuffer = {
 .outputs   = NULL,
 FILTER_QUERY_FUNC(asink_query_formats),
 };
+
+static const AVFilterPad avfilter_ssink_sbuffer_inputs[] = {
+{
+.name = "default",
+.type = AVMEDIA_TYPE_SUBTITLE,
+},
+};
+
+const AVFilter ff_ssink_sbuffer = {
+.name  = "sbuffersink",
+.description   = NULL_IF_CONFIG_SMALL("Buffer subtitle frames, and make 
them available to the end of the filter graph."),
+.priv_class= &sbuffersink_class,
+.priv_size = sizeof(BufferSinkContext),
+.init  = common_init,
+.activate  = activate,
+FILTER_INPUTS(avfilter_ssink_sbuffer_inputs),
+.outputs   = NULL,
+FILTER_QUERY_FUNC(ssink_query_formats),
+};
diff --git a/libavfilter/buffersink.h b/libavfilter/buffersink.h
index 69ed0f29a8..11905abdc5 100644
--- a/libavfilter/buffersink.h
+++ b/libavfilter/buffersink.h
@@ -129,6 +129,13 @@ typedef struct AVABufferSinkParams {
  */
 attribute_deprecated
 AVABufferSinkParams *av_abuffersink_params_alloc(void);
+
+/**
+ * Deprecated and unused struct to use for initializing an sbuffersink context.
+ */
+typedef struct AVSBufferSinkParams {
+const int *subtitle_type;
+} AVSBufferSinkParams;
 #endif
 
 /**
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
index b0611872f1..d2362999a2 100644
--- a/liba

[FFmpeg-devel] [PATCH v3 07/26] fftools/play, probe: Adjust for subtitle changes

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 fftools/ffplay.c  | 102 +-
 fftools/ffprobe.c |  47 +
 2 files changed, 77 insertions(+), 72 deletions(-)

diff --git a/fftools/ffplay.c b/fftools/ffplay.c
index e7b20be76b..94286eb678 100644
--- a/fftools/ffplay.c
+++ b/fftools/ffplay.c
@@ -152,7 +152,6 @@ typedef struct Clock {
 /* Common struct for handling all types of decoded data and allocated render 
buffers. */
 typedef struct Frame {
 AVFrame *frame;
-AVSubtitle sub;
 int serial;
 double pts;   /* presentation timestamp for the frame */
 double duration;  /* estimated duration of the frame */
@@ -586,7 +585,7 @@ static int decoder_init(Decoder *d, AVCodecContext *avctx, 
PacketQueue *queue, S
 return 0;
 }
 
-static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
+static int decoder_decode_frame(Decoder *d, AVFrame *frame) {
 int ret = AVERROR(EAGAIN);
 
 for (;;) {
@@ -620,6 +619,9 @@ static int decoder_decode_frame(Decoder *d, AVFrame *frame, 
AVSubtitle *sub) {
 }
 }
 break;
+case AVMEDIA_TYPE_SUBTITLE:
+ret = avcodec_receive_frame(d->avctx, frame);
+break;
 }
 if (ret == AVERROR_EOF) {
 d->finished = d->pkt_serial;
@@ -652,25 +654,11 @@ static int decoder_decode_frame(Decoder *d, AVFrame 
*frame, AVSubtitle *sub) {
 av_packet_unref(d->pkt);
 } while (1);
 
-if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
-int got_frame = 0;
-ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, d->pkt);
-if (ret < 0) {
-ret = AVERROR(EAGAIN);
-} else {
-if (got_frame && !d->pkt->data) {
-d->packet_pending = 1;
-}
-ret = got_frame ? 0 : (d->pkt->data ? AVERROR(EAGAIN) : 
AVERROR_EOF);
-}
-av_packet_unref(d->pkt);
+if (avcodec_send_packet(d->avctx, d->pkt) == AVERROR(EAGAIN)) {
+av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet both 
returned EAGAIN, which is an API violation.\n");
+d->packet_pending = 1;
 } else {
-if (avcodec_send_packet(d->avctx, d->pkt) == AVERROR(EAGAIN)) {
-av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet 
both returned EAGAIN, which is an API violation.\n");
-d->packet_pending = 1;
-} else {
-av_packet_unref(d->pkt);
-}
+av_packet_unref(d->pkt);
 }
 }
 }
@@ -683,7 +671,6 @@ static void decoder_destroy(Decoder *d) {
 static void frame_queue_unref_item(Frame *vp)
 {
 av_frame_unref(vp->frame);
-avsubtitle_free(&vp->sub);
 }
 
 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, 
int keep_last)
@@ -981,7 +968,7 @@ static void video_image_display(VideoState *is)
 if (frame_queue_nb_remaining(&is->subpq) > 0) {
 sp = frame_queue_peek(&is->subpq);
 
-if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 
1000)) {
+if (vp->pts >= sp->pts) {
 if (!sp->uploaded) {
 uint8_t* pixels[4];
 int pitch[4];
@@ -993,25 +980,27 @@ static void video_image_display(VideoState *is)
 if (realloc_texture(&is->sub_texture, 
SDL_PIXELFORMAT_ARGB, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
 return;
 
-for (i = 0; i < sp->sub.num_rects; i++) {
-AVSubtitleRect *sub_rect = sp->sub.rects[i];
+for (i = 0; i < sp->frame->num_subtitle_areas; i++) {
+AVSubtitleArea *area = sp->frame->subtitle_areas[i];
+SDL_Rect sdl_rect = { .x = area->x, .y = area->y, .w = 
area->w, .h = area->h };
 
-sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
-sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
-sub_rect->w = av_clip(sub_rect->w, 0, sp->width  - 
sub_rect->x);
-sub_rect->h = av_clip(sub_rect->h, 0, sp->height - 
sub_rect->y);
+area->x = av_clip(area->x, 0, sp->width );
+area->y = av_clip(area->y, 0, sp->height);
+area->w = av_clip(area->w, 0, sp->width  - area->x);
+area->h = av_clip(area->h, 0, sp->height - area->y);
 
 is->sub_convert_ctx = 
sws_getCachedContext(is->sub_convert_ctx,
-sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
-sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
+  

[FFmpeg-devel] [PATCH v3 12/26] avfilter/overlaygraphicsubs: Add overlaygraphicsubs and graphicsub2video filters

2022-01-19 Thread ffmpegagent
From: softworkz 

- overlaygraphicsubs (VS -> V)
  Overlay graphic subtitles onto a video stream

- graphicsub2video {S -> V)
  Converts graphic subtitles to video frames (with alpha)
  Gets auto-inserted for retaining compatibility with
  sub2video command lines

Signed-off-by: softworkz 
---
 doc/filters.texi| 118 +
 libavfilter/Makefile|   2 +
 libavfilter/allfilters.c|   2 +
 libavfilter/vf_overlaygraphicsubs.c | 765 
 4 files changed, 887 insertions(+)
 create mode 100644 libavfilter/vf_overlaygraphicsubs.c

diff --git a/doc/filters.texi b/doc/filters.texi
index 248c09caf8..2bd3737cf5 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -25764,6 +25764,124 @@ tools.
 
 @c man end VIDEO SINKS
 
+@chapter Subtitle Filters
+@c man begin SUBTITLE FILTERS
+
+When you configure your FFmpeg build, you can disable any of the
+existing filters using @code{--disable-filters}.
+
+Below is a description of the currently available subtitle filters.
+
+@section graphicsub2video
+
+Renders graphic subtitles as video frames.
+
+This filter replaces the previous "sub2video" hack which did the conversion 
implicitly and up-front as subtitle filtering wasn't possible at that time.
+To retain compatibility with earlier sub2video command lines, this filter is 
being auto-inserted in those cases.
+
+For overlaying graphicsal subtitles it is recommended to use the 
'overlay_graphicsubs' filter which is more efficient and takes less processing 
resources.
+
+This filter is still useful in cases where the overlay is done with hardware 
acceleration (e.g. overlay_qsv, overlay_vaapi, overlay_cuda) for preparing the 
overlay frames.
+
+Inputs:
+@itemize
+@item 0: Subtitles [BITMAP]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Video [RGB32]
+@end itemize
+
+
+It accepts the following parameters:
+
+@table @option
+@item size, s
+Set the size of the output video frame.
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Overlay PGS subtitles
+(not recommended - better use overlay_graphicsubs)
+@example
+ffmpeg -i 
"https://streams.videolan.org/samples/sub/PGS/Girl_With_The_Dragon_Tattoo_2%3A23%3A56.mkv";
 -filter_complex "[0:1]graphicsub2video[subs];[0:0][subs]overlay" output.mp4
+@end example
+
+@item
+Overlay PGS subtitles implicitly
+The graphicsub2video is inserted automatically for compatibility with legacy 
command lines.
+@example
+ffmpeg -i 
"https://streams.videolan.org/samples/sub/PGS/Girl_With_The_Dragon_Tattoo_2%3A23%3A56.mkv";
 -filter_complex "[0:0][0:1]overlay" output.mp4
+@end example
+@end itemize
+
+@section overlaygraphicsubs
+
+Overlay graphic subtitles onto a video stream.
+
+This filter can blend graphical subtitles on a video stream directly, i.e. 
without creating full-size alpha images first.
+The blending operation is limited to the area of the subtitle rectangles, 
which also means that no processing is done at times where no subtitles are to 
be displayed.
+
+Inputs:
+@itemize
+@item 0: Video [YUV420P, YUV422P, YUV444P, ARGB, RGBA, ABGR, BGRA, RGB24, 
BGR24]
+@item 1: Subtitles [BITMAP]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Video (same as input)
+@end itemize
+
+It accepts the following parameters:
+
+@table @option
+@item x
+@item y
+Set the expression for the x and y coordinates of the overlaid video
+on the main video. Default value is "0" for both expressions. In case
+the expression is invalid, it is set to a huge value (meaning that the
+overlay will not be displayed within the output visible area).
+
+@item eof_action
+See @ref{framesync}.
+
+@item eval
+Set when the expressions for @option{x}, and @option{y} are evaluated.
+
+It accepts the following values:
+@table @samp
+@item init
+only evaluate expressions once during the filter initialization or
+when a command is processed
+
+@item frame
+evaluate expressions for each incoming frame
+@end table
+
+Default value is @samp{frame}.
+
+@item shortest
+See @ref{framesync}.
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Overlay PGS subtitles
+@example
+ffmpeg -i 
"https://streams.videolan.org/samples/sub/PGS/Girl_With_The_Dragon_Tattoo_2%3A23%3A56.mkv";
 -filter_complex "[0:0][0:1]overlaygraphicsubs" output.mp4
+@end example
+@end itemize
+@c man end SUBTITLE FILTERS
+
 @chapter Multimedia Filters
 @c man begin MULTIMEDIA FILTERS
 
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index f1176644c9..c326b8d32b 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -298,6 +298,7 @@ OBJS-$(CONFIG_GBLUR_FILTER)  += vf_gblur.o
 OBJS-$(CONFIG_GBLUR_VULKAN_FILTER)   += vf_gblur_vulkan.o vulkan.o 
vulkan_filter.o
 OBJS-$(CONFIG_GEQ_FILTER)+= vf_geq.o
 OBJS-$(CONFIG_GRADFUN_FILTER)+= vf_gradfun.o
+OBJS-$(CONFIG_GRAPHICSUB2VIDEO_FILTER)   += vf_overlaygraphicsubs.o 
framesync.o
 OBJS-$(CONFIG_GRAPHMONITOR_FILTER)   += f_graphmonitor.o
 OBJS-$(CONFIG_GRAYWORLD_FIL

[FFmpeg-devel] [PATCH v3 08/26] avfilter/subtitles: Add subtitles.c for subtitle frame allocation

2022-01-19 Thread ffmpegagent
From: softworkz 

Analog to avfilter/video.c and avfilter/audio.c

Signed-off-by: softworkz 
---
 libavfilter/Makefile|  1 +
 libavfilter/avfilter.c  |  4 +++
 libavfilter/internal.h  |  1 +
 libavfilter/subtitles.c | 63 +
 libavfilter/subtitles.h | 44 
 5 files changed, 113 insertions(+)
 create mode 100644 libavfilter/subtitles.c
 create mode 100644 libavfilter/subtitles.h

diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 282967144b..f1176644c9 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -19,6 +19,7 @@ OBJS = allfilters.o   
  \
framequeue.o \
graphdump.o  \
graphparser.o\
+   subtitles.o  \
video.o  \
 
 OBJS-$(HAVE_THREADS) += pthread.o
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 7362bcdab5..df5b8f483c 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -43,6 +43,7 @@
 #include "formats.h"
 #include "framepool.h"
 #include "internal.h"
+#include "subtitles.h"
 
 #include "libavutil/ffversion.h"
 const char av_filter_ffversion[] = "FFmpeg version " FFMPEG_VERSION;
@@ -1475,6 +1476,9 @@ int ff_inlink_make_frame_writable(AVFilterLink *link, 
AVFrame **rframe)
 case AVMEDIA_TYPE_AUDIO:
 out = ff_get_audio_buffer(link, frame->nb_samples);
 break;
+case AVMEDIA_TYPE_SUBTITLE:
+out = ff_get_subtitles_buffer(link, link->format);
+break;
 default:
 return AVERROR(EINVAL);
 }
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index 1099b82b4b..fc09ef574c 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -90,6 +90,7 @@ struct AVFilterPad {
 union {
 AVFrame *(*video)(AVFilterLink *link, int w, int h);
 AVFrame *(*audio)(AVFilterLink *link, int nb_samples);
+AVFrame *(*subtitle)(AVFilterLink *link, int format);
 } get_buffer;
 
 /**
diff --git a/libavfilter/subtitles.c b/libavfilter/subtitles.c
new file mode 100644
index 00..951bfd612c
--- /dev/null
+++ b/libavfilter/subtitles.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/common.h"
+
+#include "subtitles.h"
+#include "avfilter.h"
+#include "internal.h"
+
+
+AVFrame *ff_null_get_subtitles_buffer(AVFilterLink *link, int format)
+{
+return ff_get_subtitles_buffer(link->dst->outputs[0], format);
+}
+
+AVFrame *ff_default_get_subtitles_buffer(AVFilterLink *link, int format)
+{
+AVFrame *frame;
+
+frame = av_frame_alloc();
+if (!frame)
+return NULL;
+
+frame->format = format;
+frame->type = AVMEDIA_TYPE_SUBTITLE;
+
+if (av_frame_get_buffer2(frame, 0) < 0) {
+av_frame_free(&frame);
+return NULL;
+}
+
+return frame;
+}
+
+AVFrame *ff_get_subtitles_buffer(AVFilterLink *link, int format)
+{
+AVFrame *ret = NULL;
+
+if (link->dstpad->get_buffer.subtitle)
+ret = link->dstpad->get_buffer.subtitle(link, format);
+
+if (!ret)
+ret = ff_default_get_subtitles_buffer(link, format);
+
+return ret;
+}
diff --git a/libavfilter/subtitles.h b/libavfilter/subtitles.h
new file mode 100644
index 00..4a9115126e
--- /dev/null
+++ b/libavfilter/subtitles.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * 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

[FFmpeg-devel] [PATCH v3 13/26] avfilter/overlaytextsubs: Add overlaytextsubs and textsubs2video filters

2022-01-19 Thread ffmpegagent
From: softworkz 

- overlaytextsubs {VS -> V)
  Overlay text subtitles onto a video stream.

- textsubs2video {S -> V)
  Converts text subtitles to video frames

Signed-off-by: softworkz 
---
 configure|   2 +
 doc/filters.texi | 113 ++
 libavfilter/Makefile |   2 +
 libavfilter/allfilters.c |   6 +-
 libavfilter/vf_overlaytextsubs.c | 678 +++
 5 files changed, 799 insertions(+), 2 deletions(-)
 create mode 100644 libavfilter/vf_overlaytextsubs.c

diff --git a/configure b/configure
index 1928a77344..7b66e315f2 100755
--- a/configure
+++ b/configure
@@ -3692,6 +3692,7 @@ overlay_qsv_filter_deps="libmfx"
 overlay_qsv_filter_select="qsvvpp"
 overlay_vaapi_filter_deps="vaapi VAProcPipelineCaps_blend_flags"
 overlay_vulkan_filter_deps="vulkan spirv_compiler"
+overlaytextsubs_filter_deps="avcodec libass"
 owdenoise_filter_deps="gpl"
 pad_opencl_filter_deps="opencl"
 pan_filter_deps="swresample"
@@ -3736,6 +3737,7 @@ superequalizer_filter_deps="avcodec"
 superequalizer_filter_select="rdft"
 surround_filter_deps="avcodec"
 surround_filter_select="rdft"
+textsub2video_filter_deps="avcodec libass"
 tinterlace_filter_deps="gpl"
 tinterlace_merge_test_deps="tinterlace_filter"
 tinterlace_pad_test_deps="tinterlace_filter"
diff --git a/doc/filters.texi b/doc/filters.texi
index 2bd3737cf5..02a854851c 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -25880,6 +25880,119 @@ Overlay PGS subtitles
 ffmpeg -i 
"https://streams.videolan.org/samples/sub/PGS/Girl_With_The_Dragon_Tattoo_2%3A23%3A56.mkv";
 -filter_complex "[0:0][0:1]overlaygraphicsubs" output.mp4
 @end example
 @end itemize
+
+@section overlaytextsubs
+
+Overlay text subtitles onto a video stream.
+
+This filter supersedes the classic @ref{subtitles} filter opposed to which it 
does no longer require to open and access the source stream separately, which 
is often causing problems or doesn't even work for non-local or slow sources.
+
+Inputs:
+@itemize
+@item 0: Video [YUV420P, YUV422P, YUV444P, ARGB, RGBA, ABGR, BGRA, RGB24, 
BGR24]
+@item 1: Subtitles [TEXT]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Video (same as input)
+@end itemize
+
+It accepts the following parameters:
+
+@table @option
+
+@item alpha
+Process alpha channel, by default alpha channel is untouched.
+
+@item fonts_dir
+Set a directory path containing fonts that can be used by the filter.
+These fonts will be used in addition to whatever the font provider uses.
+
+@item default_font_path
+Path to a font file to be used as the default font.
+
+@item font_size
+Set the default font size.
+
+@item fontconfig_file
+Path to ASS fontconfig configuration file.
+
+@item force_style
+Override default style or script info parameters of the subtitles. It accepts a
+string containing ASS style format @code{KEY=VALUE} couples separated by ",".
+
+@item margin
+Set the rendering margin in pixels.
+
+@item render_latest_only
+For rendering, alway use the latest event only, which is covering the given 
point in time
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Overlay ASS subtitles with animations:
+@example
+ffmpeg -i 
"http://streams.videolan.org/samples/sub/SSA/subtitle_testing_complex.mkv"; 
-filter_complex "[0:v]overlaytextsubs" -map 0 -y out.mkv
+@end example
+@end itemize
+
+@section textsub2video
+
+Converts text subtitles to video frames.
+
+For overlaying text subtitles onto video frames it is recommended to use the 
overlay_textsubs filter.
+The textsub2video is useful for for creating transparent text-frames when 
overlay is done via hw acceleration
+
+Inputs:
+@itemize
+@item 0: Subtitles [TEXT]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Video [RGB32]
+@end itemize
+
+It accepts the following parameters:
+
+@table @option
+
+@item rate, r
+Set the framerate for updating overlay frames.
+Normally, overlay frames will only be updated each time when the subtitles to 
display are changing.
+In cases where subtitles include advanced features (like animation), this 
parameter determines the frequency by which the overlay frames should be 
updated.
+
+@item size, s
+Set the output frame size.
+Allows to override the size of output video frames.
+
+@item fonts_dir
+Set a directory path containing fonts that can be used by the filter.
+These fonts will be used in addition to whatever the font provider uses.
+
+@item default_font_path
+Path to a font file to be used as the default font.
+
+@item font_size
+Set the default font size.
+
+@item fontconfig_file
+Path to ASS fontconfig configuration file.
+
+@item force_style
+Override default style or script info parameters of the subtitles. It accepts a
+string containing ASS style format @code{KEY=VALUE} couples separated by ",".
+
+@item margin
+Set the rendering margin in pixels.
+
+@item render_latest_only
+For rendering, alway use the latest event only, which is covering the given 
point in time.
+@end table
+
 @c man end SUBTITLE FILTERS
 

[FFmpeg-devel] [PATCH v3 14/26] avfilter/textmod: Add textmod, censor and show_speaker filters

2022-01-19 Thread ffmpegagent
From: softworkz 

- textmod {S -> S)
  Modify subtitle text in a number of ways

- censor {S -> S)
  Censor subtitles using a word list

- show_speaker {S -> S)
  Prepend speaker names from ASS subtitles to the visible text lines

Signed-off-by: softworkz 
---
 doc/filters.texi | 206 
 libavfilter/Makefile |   5 +
 libavfilter/allfilters.c |   3 +
 libavfilter/sf_textmod.c | 710 +++
 4 files changed, 924 insertions(+)
 create mode 100644 libavfilter/sf_textmod.c

diff --git a/doc/filters.texi b/doc/filters.texi
index 02a854851c..6559f9d101 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -25772,6 +25772,145 @@ existing filters using @code{--disable-filters}.
 
 Below is a description of the currently available subtitle filters.
 
+
+@section censor
+
+Censor selected words in text subtitles.
+
+Inputs:
+@itemize
+@item 0: Subtitles[TEXT]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Subtitles[TEXT]
+@end itemize
+
+It accepts the following parameters:
+
+@table @option
+@item mode
+The censoring mode to apply.
+
+Supported censoring modes are:
+
+@table @var
+@item 0, keep_first_last
+Replace all characters with the 'censor_char' except the first and the last 
character of a word.
+For words with less than 4 characters, the last character will be replaced as 
well.
+For words with less than 3 characters, the first character will be replaced as 
well.
+@item 1, keep_first
+Replace all characters with the 'censor_char' except the first character of a 
word.
+For words with less than 3 characters, the first character will be replaced as 
well.
+@item 2, all
+Replace all characters with the 'censor_char'.
+@end table
+
+@item words
+A list of words to censor, separated by 'separator'.
+
+@item words_file
+Specify a file from which to load the contents for the 'words' parameter.
+
+@item censor_char
+Single character used as replacement for censoring.
+
+@item separator
+Delimiter character for words. Used with replace_words and remove_words- Must 
be a single character.
+The default is '.'.
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Censor a few given words with a pound character.
+@example
+ffmpeg -i 
"http://streams.videolan.org/samples/sub/SSA/subtitle_testing_complex.mkv"; 
-filter_complex 
"[0:1]censor=words='diss,louder,hope,beam,word':censor_char='#'" -map 0 -y 
output.mkv
+@end example
+@end itemize
+
+
+@section textmod
+
+Modify subtitle text in a number of ways.
+
+Inputs:
+@itemize
+@item 0: Subtitles[TEXT]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Subtitles[TEXT]
+@end itemize
+
+It accepts the following parameters:
+
+@table @option
+@item mode
+The kind of text modification to apply
+
+Supported operation modes are:
+
+@table @var
+@item 0, leet
+Convert subtitle text to 'leet speak'. It's primarily useful for testing as 
the modification will be visible with almost all text lines.
+@item 1, to_upper
+Change all text to upper case. Might improve readability.
+@item 2, to_lower
+Change all text to lower case.
+@item 3, replace_chars
+Replace one or more characters. Requires the find and replace parameters to be 
specified.
+Both need to be equal in length.
+The first char in find is replaced by the first char in replace, same for all 
subsequent chars.
+@item 4, remove_chars
+Remove certain characters. Requires the find parameter to be specified.
+All chars in the find parameter string will be removed from all subtitle text.
+@item 5, replace_words
+Replace one or more words. Requires the find and replace parameters to be 
specified. Multiple words must be separated by the delimiter char specified vie 
the separator parameter (default: ',').
+The number of words in the find and replace parameters needs to be equal.
+The first word in find is replaced by the first word in replace, same for all 
subsequent words
+@item 6, remove_words
+Remove certain words. Requires the find parameter to be specified. Multiple 
words must be separated by the delimiter char specified vie the separator 
parameter (default: ',').
+All words in the find parameter string will be removed from all subtitle text.
+@end table
+
+@item find
+Required for replace_chars, remove_chars, replace_words and remove_words.
+
+@item find_file
+Specify a file from which to load the contents for the 'find' parameter.
+
+@item replace
+Required for replace_chars and replace_words.
+
+@item replace_file
+Specify a file from which to load the contents for the 'replace' parameter.
+
+@item separator
+Delimiter character for words. Used with replace_words and remove_words- Must 
be a single character.
+The default is '.'.
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Change all characters to upper case while keeping all styles and animations:
+@example
+ffmpeg -i "https://streams.videolan.org/ffmpeg/mkv_subtitles.mkv"; 
-filter_complex "[0:s]textmod=mode=to_upper" -map 0 -y out.mkv
+@end example
+@item
+Remove a set of symbol characters for am i

[FFmpeg-devel] [PATCH v3 15/26] avfilter/stripstyles: Add stripstyles filter

2022-01-19 Thread ffmpegagent
From: softworkz 

- stripstyles {S -> S)
  Remove all inline styles from subtitle events

Signed-off-by: softworkz 
---
 doc/filters.texi |  37 ++
 libavfilter/Makefile |   1 +
 libavfilter/allfilters.c |   1 +
 libavfilter/sf_stripstyles.c | 211 +++
 4 files changed, 250 insertions(+)
 create mode 100644 libavfilter/sf_stripstyles.c

diff --git a/doc/filters.texi b/doc/filters.texi
index 6559f9d101..2f0e560ca0 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -25832,6 +25832,43 @@ ffmpeg -i 
"http://streams.videolan.org/samples/sub/SSA/subtitle_testing_complex.
 @end example
 @end itemize
 
+@section stripstyles
+
+Remove all inline styles from subtitle events.
+
+Inputs:
+@itemize
+@item 0: Subtitles[TEXT]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Subtitles[TEXT]
+@end itemize
+
+It accepts the following parameters:
+
+@table @option
+@item remove_animated
+Also remove text which is subject to animation (default: true)
+Usually, animated text elements are used used in addition to static subtitle 
lines for creating effects, so in most cases it is safe to remove the animation 
content.
+If subtitle text is missing, try setting this to false.
+
+@item select_layer
+Process only ASS subtitle events from a specific layer. This allows to filter 
out certain effects where an ASS author duplicates the text onto multiple 
layers.
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Remove styles and animations from ASS subtitles and output events from ass 
layer 0 only. Then convert asn save as SRT stream:
+@example
+ffmpeg -i 
"https://streams.videolan.org/samples/sub/SSA/subtitle_testing_complex.mkv"; 
-filter_complex "[0:1]stripstyles=select_layer=0" -map 0 -c:s srt output.mkv
+@end example
+@end itemize
+
 
 @section textmod
 
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 4579b7c8c0..9c512e3527 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -566,6 +566,7 @@ OBJS-$(CONFIG_NULLSINK_FILTER)   += 
vsink_nullsink.o
 OBJS-$(CONFIG_CENSOR_FILTER) += sf_textmod.o
 OBJS-$(CONFIG_SHOW_SPEAKER_FILTER)   += sf_textmod.o
 OBJS-$(CONFIG_TEXTMOD_FILTER)+= sf_textmod.o
+OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
 
 # multimedia filters
 OBJS-$(CONFIG_ABITSCOPE_FILTER)  += avf_abitscope.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 9c489fdc66..23f65533a1 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -550,6 +550,7 @@ extern const AVFilter ff_avf_showwavespic;
 extern const AVFilter ff_vaf_spectrumsynth;
 extern const AVFilter ff_sf_censor;
 extern const AVFilter ff_sf_showspeaker;
+extern const AVFilter ff_sf_stripstyles;
 extern const AVFilter ff_sf_textmod;
 extern const AVFilter ff_svf_graphicsub2video;
 extern const AVFilter ff_svf_textsub2video;
diff --git a/libavfilter/sf_stripstyles.c b/libavfilter/sf_stripstyles.c
new file mode 100644
index 00..bc3c5d1441
--- /dev/null
+++ b/libavfilter/sf_stripstyles.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * text subtitle filter which removes inline-styles from subtitles
+ */
+
+#include "libavutil/opt.h"
+#include "internal.h"
+#include "libavutil/ass_split_internal.h"
+#include "libavutil/bprint.h"
+
+typedef struct StripStylesContext {
+const AVClass *class;
+enum AVSubtitleType format;
+int remove_animated;
+int select_layer;
+} StripStylesContext;
+
+typedef struct DialogContext {
+StripStylesContext* ss_ctx;
+AVBPrint buffer;
+int drawing_scale;
+int is_animated;
+} DialogContext;
+
+static void dialog_text_cb(void *priv, const char *text, int len)
+{
+DialogContext *s = priv;
+
+av_log(s->ss_ctx, AV_LOG_DEBUG, "dialog_text_cb: %s\n", text);
+
+if (!s->drawing_scale && (!s->is_animated || !s->ss_ctx->remove_animated))
+av_bprint_append_data(&s->buffer, text, len);
+}
+
+static void dialog_new_line_cb(void *priv, int forced)
+{
+DialogContext *s = priv;
+if (!s->drawing_scale && !s->is_animated)
+av_bprint_append_data(&s->buffer, forced ? "\\N" : "\\n", 2);
+}

[FFmpeg-devel] [PATCH v3 16/26] avfilter/splitcc: Add splitcc filter for closed caption handling

2022-01-19 Thread ffmpegagent
From: softworkz 

- splitcc {V -> VS)
  Extract closed-caption (A53) data from video
  frames as subtitle Frames

ffmpeg -y -loglevel verbose -i "https://streams.videolan.org/streams
/ts/CC/NewsStream-608-ac3.ts" -filter_complex "[0:v]splitcc[vid1],
textmod=mode=remove_chars:find='@',[vid1]overlay_textsubs" output.mkv

Signed-off-by: softworkz 
---
 configure|   1 +
 doc/filters.texi |  63 +++
 libavfilter/Makefile |   1 +
 libavfilter/allfilters.c |   1 +
 libavfilter/sf_splitcc.c | 395 +++
 5 files changed, 461 insertions(+)
 create mode 100644 libavfilter/sf_splitcc.c

diff --git a/configure b/configure
index 7b66e315f2..2a561b6f75 100755
--- a/configure
+++ b/configure
@@ -3730,6 +3730,7 @@ spp_filter_select="fft idctdsp fdctdsp me_cmp pixblockdsp"
 sr_filter_deps="avformat swscale"
 sr_filter_select="dnn"
 stereo3d_filter_deps="gpl"
+splitcc_filter_deps="avcodec"
 subtitles_filter_deps="avformat avcodec libass"
 super2xsai_filter_deps="gpl"
 pixfmts_super2xsai_test_deps="super2xsai_filter"
diff --git a/doc/filters.texi b/doc/filters.texi
index 2f0e560ca0..c7a11a0896 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -26182,6 +26182,69 @@ ffmpeg -i INPUT -filter_complex 
"showspeaker=format=colon:style='@{\\c&HDD&\
 @end example
 @end itemize
 
+
+@section splitcc
+
+Split-out closed-caption/A53 subtitles from video frame side data.
+
+This filter provides an input and an output for video frames, which are just 
passed through without modification.
+The second out provides subtitle frames which are extracted from video frame 
side data.
+
+Inputs:
+@itemize
+@item 0: Video [ALL]
+@end itemize
+
+Outputs:
+@itemize
+@item 0: Video (same as input)
+@item 1: Subtitles [TEXT]
+@end itemize
+
+It accepts the following parameters:
+
+@table @option
+
+@item use_cc_styles
+Emit closed caption style header.
+This will make closed captions appear in white font with a black rectangle 
background.
+
+@item real_time
+Emit subtitle events as they are decoded for real-time display.
+
+@item real_time_latency_msec
+Minimum elapsed time between emitting real-time subtitle events.
+Only applies to real_time mode.
+
+@item data_field
+Select data field. Possible values:
+
+@table @samp
+@item auto
+Pick first one that appears.
+@item first
+@item second
+@end table
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Extract closed captions as text subtitle stream and overlay it onto the video 
in cc style (black bar background):
+@example
+ffmpeg -i "https://streams.videolan.org/streams/ts/CC/NewsStream-608-ac3.ts"; 
-filter_complex  
"[0:v:0]splitcc=use_cc_styles=1[vid1][sub1];[vid1][sub1]overlaytextsubs" 
output.mkv
+@end example
+
+@item
+A nicer variant, using realtime output from cc_dec and rendering it with the 
render_latest_only parameter from overlaytextsubs to avoid ghosting by timely 
overlap.
+@example
+ffmpeg -i "https://streams.videolan.org/streams/ts/CC/NewsStream-608-ac3.ts"; 
-filter_complex  
"[0:v:0]splitcc=real_time=1:real_time_latency_msec=200[vid1][sub1];[vid1][sub1]overlaytextsubs=render_latest_only=1"
 output.mkv
+@end example
+@end itemize
+
+
 @section textsub2video
 
 Converts text subtitles to video frames.
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 9c512e3527..b2e715cf8a 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -566,6 +566,7 @@ OBJS-$(CONFIG_NULLSINK_FILTER)   += 
vsink_nullsink.o
 OBJS-$(CONFIG_CENSOR_FILTER) += sf_textmod.o
 OBJS-$(CONFIG_SHOW_SPEAKER_FILTER)   += sf_textmod.o
 OBJS-$(CONFIG_TEXTMOD_FILTER)+= sf_textmod.o
+OBJS-$(CONFIG_SPLITCC_FILTER)+= sf_splitcc.o
 OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
 
 # multimedia filters
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 23f65533a1..4996d3d27a 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -550,6 +550,7 @@ extern const AVFilter ff_avf_showwavespic;
 extern const AVFilter ff_vaf_spectrumsynth;
 extern const AVFilter ff_sf_censor;
 extern const AVFilter ff_sf_showspeaker;
+extern const AVFilter ff_sf_splitcc;
 extern const AVFilter ff_sf_stripstyles;
 extern const AVFilter ff_sf_textmod;
 extern const AVFilter ff_svf_graphicsub2video;
diff --git a/libavfilter/sf_splitcc.c b/libavfilter/sf_splitcc.c
new file mode 100644
index 00..14235e822c
--- /dev/null
+++ b/libavfilter/sf_splitcc.c
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * 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
+

[FFmpeg-devel] [PATCH v3 17/26] avfilter/graphicsub2text: Add new graphicsub2text filter (OCR)

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 configure|1 +
 doc/filters.texi |   55 ++
 libavfilter/Makefile |2 +
 libavfilter/allfilters.c |1 +
 libavfilter/sf_graphicsub2text.c | 1132 ++
 5 files changed, 1191 insertions(+)
 create mode 100644 libavfilter/sf_graphicsub2text.c

diff --git a/configure b/configure
index 2a561b6f75..59d3bb86f0 100755
--- a/configure
+++ b/configure
@@ -3665,6 +3665,7 @@ frei0r_filter_deps="frei0r"
 frei0r_src_filter_deps="frei0r"
 fspp_filter_deps="gpl"
 gblur_vulkan_filter_deps="vulkan spirv_compiler"
+graphicsub2text_filter_deps="libtesseract"
 hflip_vulkan_filter_deps="vulkan spirv_compiler"
 histeq_filter_deps="gpl"
 hqdn3d_filter_deps="gpl"
diff --git a/doc/filters.texi b/doc/filters.texi
index c7a11a0896..1c0a00c7ae 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -25948,6 +25948,61 @@ ffmpeg -i 
"https://streams.videolan.org/ffmpeg/mkv_subtitles.mkv"; -filter_comple
 @end example
 @end itemize
 
+@section graphicsub2text
+
+Converts graphic subtitles to text subtitles by performing OCR.
+
+For this filter to be available, ffmpeg needs to be compiled with libtesseract 
(see https://github.com/tesseract-ocr/tesseract).
+Language models need to be downloaded from 
https://github.com/tesseract-ocr/tessdata and put into as subfolder named 
'tessdata' or into a folder specified via the environment variable 
'TESSDATA_PREFIX'.
+The path can also be specified via filter option (see below).
+
+Note: These models are including the data for both OCR modes.
+
+Inputs:
+- 0: Subtitles [bitmap]
+
+Outputs:
+- 0: Subtitles [text]
+
+It accepts the following parameters:
+
+@table @option
+@item ocr_mode
+The character recognition mode to use.
+
+Supported OCR modes are:
+
+@table @var
+@item 0, tesseract
+This is the classic libtesseract operation mode. It is fast but less accurate 
than LSTM.
+@item 1, lstm
+Newer OCR implementation based on ML models. Provides usually better results, 
requires more processing resources.
+@item 2, both
+Use a combination of both modes.
+@end table
+
+@item tessdata_path
+The path to a folder containing the language models to be used.
+
+@item language
+The recognition language. It needs to match the first three characters of a  
language model file in the tessdata path.
+
+@end table
+
+
+@subsection Examples
+
+@itemize
+@item
+Convert DVB graphic subtitles to ASS (text) subtitles
+
+Note: For this to work, you need to have the data file 'eng.traineddata' in a 
'tessdata' subfolder (see above).
+@example
+ffmpeg -loglevel verbose -i 
"https://streams.videolan.org/streams/ts/video_subs_ttxt%2Bdvbsub.ts"; 
-filter_complex "[0:13]graphicsub2text=delay_when_no_duration=1" -c:s ass -y 
output.mkv
+@end example
+@end itemize
+
+
 @section graphicsub2video
 
 Renders graphic subtitles as video frames.
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index b2e715cf8a..1397351373 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -299,6 +299,8 @@ OBJS-$(CONFIG_GBLUR_VULKAN_FILTER)   += 
vf_gblur_vulkan.o vulkan.o vulka
 OBJS-$(CONFIG_GEQ_FILTER)+= vf_geq.o
 OBJS-$(CONFIG_GRADFUN_FILTER)+= vf_gradfun.o
 OBJS-$(CONFIG_GRAPHICSUB2VIDEO_FILTER)   += vf_overlaygraphicsubs.o 
framesync.o
+OBJS-$(CONFIG_GRAPHICSUB2TEXT_FILTER)+= sf_graphicsub2text.o
+OBJS-$(CONFIG_GRAPHICSUB2VIDEO_FILTER)   += vf_overlaygraphicsubs.o 
framesync.o
 OBJS-$(CONFIG_GRAPHMONITOR_FILTER)   += f_graphmonitor.o
 OBJS-$(CONFIG_GRAYWORLD_FILTER)  += vf_grayworld.o
 OBJS-$(CONFIG_GREYEDGE_FILTER)   += vf_colorconstancy.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 4996d3d27a..544eca616a 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -549,6 +549,7 @@ extern const AVFilter ff_avf_showwaves;
 extern const AVFilter ff_avf_showwavespic;
 extern const AVFilter ff_vaf_spectrumsynth;
 extern const AVFilter ff_sf_censor;
+extern const AVFilter ff_sf_graphicsub2text;
 extern const AVFilter ff_sf_showspeaker;
 extern const AVFilter ff_sf_splitcc;
 extern const AVFilter ff_sf_stripstyles;
diff --git a/libavfilter/sf_graphicsub2text.c b/libavfilter/sf_graphicsub2text.c
new file mode 100644
index 00..9b413d314e
--- /dev/null
+++ b/libavfilter/sf_graphicsub2text.c
@@ -0,0 +1,1132 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * 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 Gene

[FFmpeg-devel] [PATCH v3 18/26] avfilter/subscale: Add filter for scaling and/or re-arranging graphical subtitles

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 configure |   1 +
 doc/filters.texi  | 164 +++
 libavfilter/Makefile  |   1 +
 libavfilter/allfilters.c  |   1 +
 libavfilter/sf_subscale.c | 884 ++
 5 files changed, 1051 insertions(+)
 create mode 100644 libavfilter/sf_subscale.c

diff --git a/configure b/configure
index 59d3bb86f0..acb788edfc 100755
--- a/configure
+++ b/configure
@@ -3732,6 +3732,7 @@ sr_filter_deps="avformat swscale"
 sr_filter_select="dnn"
 stereo3d_filter_deps="gpl"
 splitcc_filter_deps="avcodec"
+subscale_filter_deps="swscale avcodec"
 subtitles_filter_deps="avformat avcodec libass"
 super2xsai_filter_deps="gpl"
 pixfmts_super2xsai_test_deps="super2xsai_filter"
diff --git a/doc/filters.texi b/doc/filters.texi
index 1c0a00c7ae..c9a1616d84 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -26354,6 +26354,170 @@ Set the rendering margin in pixels.
 For rendering, alway use the latest event only, which is covering the given 
point in time.
 @end table
 
+@section subscale
+
+Provides high-quality scaling and rearranging functionality for graphical 
subtitles.
+
+The subscale filter provides multiple approaches for manipulating
+the size and position of graphical subtitle rectangles wich can
+be combined or used separately.
+Scaling is performed by converting the palettized subtitle bitmaps
+to RGBA and re-quantization to palette colors afterwards via elbg algorithm.
+
+The two major operations are 'scale' and 're-arrange' with the
+latter being separated as 'arrange_h' and 'arrange_v'.
+
+
+Inputs:
+- 0: Subtitles [bitmap]
+
+Outputs:
+- 0: Subtitles [bitmap]
+
+It accepts the following parameters:
+
+@table @option
+
+@item w, width
+Set the width of the output.
+Width and height in case of graphical subtitles are just indicating
+a virtual size for which the output (consisting of 0-n bitmap rectangles)
+is intended to be displayed on.
+
+@item h, height
+Set the height of the output.
+
+@item margin_h
+Sets a horizontal margin to be preserverved when using any
+of the arrange modes.
+
+@item margin_v
+Sets a vertical margin to be preserverved when using any
+of the arrange modes.
+
+@item force_original_aspect_ratio
+Enable decreasing or increasing output video width or height if necessary to
+keep the original aspect ratio. Possible values:
+
+@table @samp
+@item disable
+Scale the video as specified and disable this feature.
+
+@item decrease
+The output video dimensions will automatically be decreased if needed.
+
+@item increase
+The output video dimensions will automatically be increased if needed.
+
+@end table
+
+
+@item scale_mode
+Specifies how subtitle bitmaps should be scaled.
+The scale factor is determined by the the factor between input
+and output size.
+
+@table @samp
+@item none
+Do not apply any common scaling.
+
+@item uniform
+Uniformly scale all subtitle bitmaps including their positions.
+
+@item uniform_no_reposition
+Uniformly scale all subtitle bitmaps without changing positions.
+
+@end table
+
+
+@item arrange_h
+Specifies how subtitle bitmaps should be arranged horizontally.
+
+@item arrange_v
+Specifies how subtitle bitmaps should be arranged vertically.
+
+
+@table @samp
+@item none
+Do not rearrange subtitle bitmaps.
+
+@item margin_no_scale
+Move subtitle bitmaps to be positioned inside the specified
+margin (margin_h or margin_v) when possible and without scaling.
+
+@item margin_and_scale
+Move subtitle bitmaps to be positioned inside the specified
+margin (margin_h or margin_v) and scale in case it doesn't fit.
+
+@item snapalign_no_scale
+Categorize subtitle bitmap positions as one of left/center/right
+or top/bottom/middle based on original positioning and apply
+these alignments for the target positioning.
+No scaling will be applied.
+
+@item snapalign_and_scale
+Categorize subtitle bitmap positions as one of left/center/right
+or top/bottom/middle based on original positioning and apply
+these alignments for the target positioning.
+Bitmaps that do not fit inside the margins borders are
+scaled to fit.
+@end table
+
+@item eval
+Set evaluation mode for the expressions (@option{width}, @option{height}).
+
+It accepts the following values:
+@table @samp
+@item init
+Evaluate expressions only once during the filter initialization.
+
+@item frame
+Evaluate expressions for each incoming frame. This is way slower than the
+@samp{init} mode since it requires all the scalers to be re-computed, but it
+allows advanced dynamic expressions.
+@end table
+
+Default value is @samp{init}.
+
+
+@item num_colors
+Set the number of palette colors for output images.
+Choose the maximum (256) when further processing is done (e.g.
+overlaying on a video).
+When subtitles will be encoded as bitmap subtitles (e.g. dvbsub),
+a smaller number of palette colors (e.g. 4-16) might need to be used, depending
+on the target format and codec.
+
+@item bitmap_width_align
+@item bitmap_height_align
+Make s

[FFmpeg-devel] [PATCH v3 19/26] avfilter/subfeed: add subtitle feed filter

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/Makefile |   1 +
 libavfilter/allfilters.c |   1 +
 libavfilter/sf_subfeed.c | 366 +++
 3 files changed, 368 insertions(+)
 create mode 100644 libavfilter/sf_subfeed.c

diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 94160d1429..ad8a5a9d18 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -571,6 +571,7 @@ OBJS-$(CONFIG_TEXTMOD_FILTER)+= sf_textmod.o
 OBJS-$(CONFIG_SPLITCC_FILTER)+= sf_splitcc.o
 OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
 OBJS-$(CONFIG_SUBSCALE_FILTER)   += sf_subscale.o
+OBJS-$(CONFIG_SUBFEED_FILTER)+= sf_subfeed.o
 
 # multimedia filters
 OBJS-$(CONFIG_ABITSCOPE_FILTER)  += avf_abitscope.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 487e2bd6a8..fe1aec093b 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -554,6 +554,7 @@ extern const AVFilter ff_sf_showspeaker;
 extern const AVFilter ff_sf_splitcc;
 extern const AVFilter ff_sf_stripstyles;
 extern const AVFilter ff_sf_subscale;
+extern const AVFilter ff_sf_subfeed;
 extern const AVFilter ff_sf_textmod;
 extern const AVFilter ff_svf_graphicsub2video;
 extern const AVFilter ff_svf_textsub2video;
diff --git a/libavfilter/sf_subfeed.c b/libavfilter/sf_subfeed.c
new file mode 100644
index 00..7df6641f6a
--- /dev/null
+++ b/libavfilter/sf_subfeed.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * subtitle filter for feeding subtitle frames into a filtergraph in a 
contiguous way
+ *
+ *
+ * also supports
+ *   - duration fixup
+ * delaying a subtitle event with unknown duration and infer duration from 
the
+ * start time of the subsequent subtitle
+ *   - scattering
+ * splitting a subtitle event with unknown duration into multiple ones with
+ * a short and fixed duration
+ *
+ */
+
+#include "filters.h"
+#include "libavutil/opt.h"
+#include "subtitles.h"
+#include "libavutil/avassert.h"
+
+enum SubFeedMode {
+FM_REPEAT,
+FM_SCATTER,
+FM_FORWARD,
+};
+
+typedef struct SubFeedContext {
+const AVClass *class;
+enum AVSubtitleType format;
+enum SubFeedMode mode;
+
+AVRational frame_rate;
+int fix_durations;
+int fix_overlap;
+
+int current_frame_isnew;
+int eof;
+int got_first_input;
+int need_frame;
+int64_t next_pts_offset;
+int64_t recent_subtitle_pts;
+
+int64_t counter;
+
+/**
+ * Queue of frames waiting to be filtered.
+ */
+FFFrameQueue fifo;
+
+} SubFeedContext;
+
+static int64_t ms_to_avtb(int64_t ms)
+{
+return av_rescale_q(ms, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q);
+}
+
+static int64_t avtb_to_ms(int64_t avtb)
+{
+return av_rescale_q(avtb, AV_TIME_BASE_Q, (AVRational){ 1, 1000 });
+}
+
+static int init(AVFilterContext *ctx)
+{
+SubFeedContext *s = ctx->priv;
+
+ff_framequeue_init(&s->fifo, NULL);
+
+return 0;
+}
+
+static void uninit(AVFilterContext *ctx)
+{
+SubFeedContext *s = ctx->priv;
+ff_framequeue_free(&s->fifo);
+}
+
+static int config_input(AVFilterLink *link)
+{
+const subfeedContext *context = link->dst->priv;
+
+return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+AVFilterFormats *formats;
+AVFilterLink *inlink0 = ctx->inputs[0];
+AVFilterLink *outlink0 = ctx->outputs[0];
+static const enum AVSubtitleType subtitle_fmts[] = { 
AV_SUBTITLE_FMT_BITMAP, AV_SUBTITLE_FMT_ASS, AV_SUBTITLE_FMT_NB };
+int ret;
+
+formats = ff_make_format_list(subtitle_fmts);
+
+if ((ret = ff_formats_ref(formats, &inlink0->outcfg.formats)) < 0)
+return ret;
+
+if ((ret = ff_formats_ref(formats, &outlink0->incfg.formats)) < 0)
+return ret;
+
+return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+SubFeedContext *s = outlink->src->priv;
+const AVFilterLink *inlink = outlink->src->inputs[0];
+
+outlink->time_base = AV_TIME_BASE_Q;
+outlink->format = inlink->format;
+outlink->w = inlink->w;
+outlink->h = inlink->h;
+
+if (s->mode == FM_FORWARD)
+

[FFmpeg-devel] [PATCH v3 20/26] avcodec/subtitles: Migrate subtitle encoders to frame-based API

2022-01-19 Thread ffmpegagent
From: softworkz 

and provide a compatibility shim for the legacy api

Signed-off-by: softworkz 
---
 libavcodec/assenc.c| 189 ++---
 libavcodec/avcodec.h   |   5 +-
 libavcodec/dvbsubenc.c |  96 ++-
 libavcodec/dvdsubenc.c | 102 
 libavcodec/encode.c|  61 +++-
 libavcodec/movtextenc.c| 114 --
 libavcodec/srtenc.c| 108 ++---
 libavcodec/tests/avcodec.c |   2 -
 libavcodec/ttmlenc.c   | 101 +++-
 libavcodec/webvttenc.c |  86 -
 libavcodec/xsubenc.c   |  88 ++---
 11 files changed, 687 insertions(+), 265 deletions(-)

diff --git a/libavcodec/assenc.c b/libavcodec/assenc.c
index b0e475834b..e1401b1ac5 100644
--- a/libavcodec/assenc.c
+++ b/libavcodec/assenc.c
@@ -22,70 +22,195 @@
 #include 
 
 #include "avcodec.h"
+#include "encode.h"
 #include "libavutil/ass_internal.h"
 #include "internal.h"
 #include "libavutil/avstring.h"
 #include "libavutil/internal.h"
 #include "libavutil/mem.h"
 
+typedef struct {
+AVCodecContext *avctx;
+AVFrame* current_frame;
+int have_frame;
+int current_area;
+} AssEncContext;
+
+static void check_write_header(AVCodecContext* avctx, const AVFrame* frame)
+{
+if (avctx->extradata_size)
+return;
+
+if (frame->subtitle_header && frame->subtitle_header->size > 0) {
+const char* subtitle_header = (char*)frame->subtitle_header->data;
+avctx->extradata_size = strlen(subtitle_header);
+avctx->extradata = av_mallocz(frame->subtitle_header->size + 1);
+memcpy(avctx->extradata, subtitle_header, avctx->extradata_size);
+avctx->extradata[avctx->extradata_size] = 0;
+}
+
+if (!avctx->extradata_size) {
+const char* subtitle_header = 
avpriv_ass_get_subtitle_header_default(0);
+if (!subtitle_header)
+return;
+
+avctx->extradata_size = strlen(subtitle_header);
+avctx->extradata = av_mallocz(avctx->extradata_size + 1);
+memcpy(avctx->extradata, subtitle_header, avctx->extradata_size);
+avctx->extradata[avctx->extradata_size] = 0;
+av_freep(&subtitle_header);
+}
+}
+
 static av_cold int ass_encode_init(AVCodecContext *avctx)
 {
-avctx->extradata = av_malloc(avctx->subtitle_header_size + 1);
-if (!avctx->extradata)
-return AVERROR(ENOMEM);
-memcpy(avctx->extradata, avctx->subtitle_header, 
avctx->subtitle_header_size);
-avctx->extradata_size = avctx->subtitle_header_size;
-avctx->extradata[avctx->extradata_size] = 0;
+AssEncContext *s = avctx->priv_data;
+
+if (avctx->subtitle_header_size) {
+avctx->extradata = av_malloc(avctx->subtitle_header_size + 1);
+if (!avctx->extradata)
+return AVERROR(ENOMEM);
+memcpy(avctx->extradata, avctx->subtitle_header, 
avctx->subtitle_header_size);
+avctx->extradata_size   = avctx->subtitle_header_size;
+avctx->extradata[avctx->extradata_size] = 0;
+}
+
+s->current_frame = av_frame_alloc();
+return 0;
+}
+
+static av_cold int ass_encode_close(AVCodecContext *avctx)
+{
+AssEncContext *s = avctx->priv_data;
+av_frame_free(&s->current_frame);
 return 0;
 }
 
-static int ass_encode_frame(AVCodecContext *avctx,
-unsigned char *buf, int bufsize,
-const AVSubtitle *sub)
+static int ass_encode_frame(AVCodecContext* avctx, AVPacket* avpkt,
+const AVFrame* frame, int* got_packet)
+{
+int ret;
+size_t req_len = 0, total_len = 0;
+
+check_write_header(avctx, frame);
+
+for (unsigned i = 0; i < frame->num_subtitle_areas; i++) {
+const char *ass = frame->subtitle_areas[i]->ass;
+
+if (frame->subtitle_areas[i]->type != AV_SUBTITLE_FMT_ASS) {
+av_log(avctx, AV_LOG_ERROR, "Only AV_SUBTITLE_FMT_ASS type 
supported.\n");
+return AVERROR(EINVAL);
+}
+
+if (ass)
+req_len += strlen(ass);
+}
+
+ret = ff_get_encode_buffer(avctx, avpkt, req_len + 1, 0);
+if (ret < 0) {
+av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+return ret;
+}
+
+for (unsigned i = 0; i < frame->num_subtitle_areas; i++) {
+const char *ass = frame->subtitle_areas[i]->ass;
+
+if (ass) {
+size_t len = av_strlcpy((char *)avpkt->data + total_len, ass, 
avpkt->size - total_len);
+total_len += len;
+}
+}
+
+avpkt->size = total_len;
+*got_packet = total_len > 0;
+
+return 0;
+}
+
+static int ass_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
 {
-int i, len, total_len = 0;
+AssEncContext *s = avctx-

[FFmpeg-devel] [PATCH v3 22/26] avutil/ass_split: Add parsing of hard-space tags (\h)

2022-01-19 Thread ffmpegagent
From: softworkz 

The \h tag in ASS/SSA is indicating a non-breaking space. See
https://github.com/Aegisub/aegisite/blob/master/source/docs/3.2/
ASS_Tags.html.md

The ass_split implementation is used by almost all text subtitle
encoders and it didn't handle this tag. Interestingly, several
tests are testing for \h parsing and had incorrect reference data
for those tests.

The \h tag is specific to ASS and doesn't have any meaning outside
of ASS.
Still, the reference data for ttmlenc, textenc and webvttenc were
full of \h tags even though this tag doesn't have a meaning there.

Signed-off-by: softworkz 
---
 libavutil/ass_split.c|  7 +++
 tests/ref/fate/.gitattributes|  3 +++
 tests/ref/fate/mov-mp4-ttml-dfxp |  8 
 tests/ref/fate/mov-mp4-ttml-stpp |  8 
 tests/ref/fate/sub-textenc   | 10 +-
 tests/ref/fate/sub-ttmlenc   |  8 
 tests/ref/fate/sub-webvttenc | 10 +-
 7 files changed, 32 insertions(+), 22 deletions(-)
 create mode 100644 tests/ref/fate/.gitattributes

diff --git a/libavutil/ass_split.c b/libavutil/ass_split.c
index c5963351fc..30512dfc74 100644
--- a/libavutil/ass_split.c
+++ b/libavutil/ass_split.c
@@ -484,6 +484,7 @@ int avpriv_ass_split_override_codes(const ASSCodesCallbacks 
*callbacks, void *pr
 while (buf && *buf) {
 if (text && callbacks->text &&
 (sscanf(buf, "\\%1[nN]", new_line) == 1 ||
+ sscanf(buf, "\\%1[hH]", new_line) == 1 ||
  !strncmp(buf, "{\\", 2))) {
 callbacks->text(priv, text, text_len);
 text = NULL;
@@ -492,6 +493,12 @@ int avpriv_ass_split_override_codes(const 
ASSCodesCallbacks *callbacks, void *pr
 if (callbacks->new_line)
 callbacks->new_line(priv, new_line[0] == 'N');
 buf += 2;
+} else if (sscanf(buf, "\\%1[hH]", new_line) == 1) {
+if (callbacks->hard_space)
+callbacks->hard_space(priv);
+else if (callbacks->text)
+callbacks->text(priv, " ", 1);
+buf += 2;
 } else if (!strncmp(buf, "{\\", 2)) {
 buf++;
 while (*buf == '\\') {
diff --git a/tests/ref/fate/.gitattributes b/tests/ref/fate/.gitattributes
new file mode 100644
index 00..19be64d085
--- /dev/null
+++ b/tests/ref/fate/.gitattributes
@@ -0,0 +1,3 @@
+sub-textenc -diff
+sub-ttmlenc -diff
+sub-webvttenc -diff
diff --git a/tests/ref/fate/mov-mp4-ttml-dfxp b/tests/ref/fate/mov-mp4-ttml-dfxp
index e24b5d618b..e565ffa1f6 100644
--- a/tests/ref/fate/mov-mp4-ttml-dfxp
+++ b/tests/ref/fate/mov-mp4-ttml-dfxp
@@ -1,9 +1,9 @@
-2e7e01c821c111466e7a2844826b7f6d *tests/data/fate/mov-mp4-ttml-dfxp.mp4
-8519 tests/data/fate/mov-mp4-ttml-dfxp.mp4
+658884e1b789e75c454b25bdf71283c9 *tests/data/fate/mov-mp4-ttml-dfxp.mp4
+8486 tests/data/fate/mov-mp4-ttml-dfxp.mp4
 #tb 0: 1/1000
 #media_type 0: data
 #codec_id 0: none
-0,  0,  0,68500, 7866, 0x456c36b7
+0,  0,  0,68500, 7833, 0x31b22193
 {
 "packets": [
 {
@@ -15,7 +15,7 @@
 "dts_time": "0.00",
 "duration": 68500,
 "duration_time": "68.50",
-"size": "7866",
+"size": "7833",
 "pos": "44",
 "flags": "K_"
 }
diff --git a/tests/ref/fate/mov-mp4-ttml-stpp b/tests/ref/fate/mov-mp4-ttml-stpp
index 77bd23b7bf..f25b5b2d28 100644
--- a/tests/ref/fate/mov-mp4-ttml-stpp
+++ b/tests/ref/fate/mov-mp4-ttml-stpp
@@ -1,9 +1,9 @@
-cbd2c7ff864a663b0d893deac5a0caec *tests/data/fate/mov-mp4-ttml-stpp.mp4
-8547 tests/data/fate/mov-mp4-ttml-stpp.mp4
+c9570de0ccebc858b0c662a7e449582c *tests/data/fate/mov-mp4-ttml-stpp.mp4
+8514 tests/data/fate/mov-mp4-ttml-stpp.mp4
 #tb 0: 1/1000
 #media_type 0: data
 #codec_id 0: none
-0,  0,  0,68500, 7866, 0x456c36b7
+0,  0,  0,68500, 7833, 0x31b22193
 {
 "packets": [
 {
@@ -15,7 +15,7 @@ cbd2c7ff864a663b0d893deac5a0caec 
*tests/data/fate/mov-mp4-ttml-stpp.mp4
 "dts_time": "0.00",
 "duration": 68500,
 "duration_time": "68.50",
-"size": "7866",
+"size": "7833",
 "pos": "44",
 "flags": "K_"
 }
diff --git a/tests/ref/fate/sub-textenc b/tests/ref/fate/sub-textenc
index 3ea56b38f0..910ca3d6e3 100644
--- a/tests/ref/fate/sub-textenc
+++ b/tests/ref/fate/sub-textenc
@@ -160,18 +160,18 @@ but show this: {normal text}
 \ N is a forced line break
 \ h is a hard space
 Normal spaces at the start and at the end of the line are trimmed while hard 
spaces are not trimmed.
-The\hline\hwill\hnever\hbreak\hautomatically\hright\hbefore\hor\hafter\ha\hhard\hspace.\h:-D
+The line will never break automatically right before or after a hard space. :-D
 
 31
 00:00:54,501 --> 00:00:56,500
 
-\h\h\h\h\hA (05 hard spaces followed by a letter)
+ A (05 hard spaces followed by a let

[FFmpeg-devel] [PATCH v3 23/26] avcodec/webvttenc: convert hard-space tags to  

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/webvttenc.c   |  6 ++
 tests/ref/fate/sub-webvttenc | 10 +-
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/libavcodec/webvttenc.c b/libavcodec/webvttenc.c
index c0436f5739..48945dcb8e 100644
--- a/libavcodec/webvttenc.c
+++ b/libavcodec/webvttenc.c
@@ -123,6 +123,11 @@ static void webvtt_new_line_cb(void *priv, int forced)
 webvtt_print(priv, "\n");
 }
 
+static void webvtt_hard_space_cb(void *priv)
+{
+webvtt_print(priv, " ");
+}
+
 static void webvtt_style_cb(void *priv, char style, int close)
 {
 if (style == 's') // strikethrough unsupported
@@ -147,6 +152,7 @@ static void webvtt_end_cb(void *priv)
 static const ASSCodesCallbacks webvtt_callbacks = {
 .text = webvtt_text_cb,
 .new_line = webvtt_new_line_cb,
+.hard_space   = webvtt_hard_space_cb,
 .style= webvtt_style_cb,
 .color= NULL,
 .font_name= NULL,
diff --git a/tests/ref/fate/sub-webvttenc b/tests/ref/fate/sub-webvttenc
index f4172dcc84..ee9de2859e 100644
--- a/tests/ref/fate/sub-webvttenc
+++ b/tests/ref/fate/sub-webvttenc
@@ -132,26 +132,26 @@ but show this: {normal text}
 \ N is a forced line break
 \ h is a hard space
 Normal spaces at the start and at the end of the line are trimmed while hard 
spaces are not trimmed.
-The line will never break automatically right before or after a hard space. :-D
+The line will never break automatically right before or after a hard space. :-D
 
 00:54.501 --> 00:56.500
 
- A (05 hard spaces followed by a letter)
+ A (05 hard spaces followed by a letter)
 A (Normal  spaces followed by a letter)
 A (No hard spaces followed by a letter)
 
 00:56.501 --> 00:58.500
- A (05 hard spaces followed by a letter)
+ A (05 hard spaces followed by a letter)
 A (Normal  spaces followed by a letter)
 A (No hard spaces followed by a letter)
 Show this: \TEST and this: \-)
 
 00:58.501 --> 01:00.500
 
-A letter followed by 05 hard spaces: A 
+A letter followed by 05 hard spaces: A 
 A letter followed by normal  spaces: A
 A letter followed by no hard spaces: A
-05 hard  spaces between letters: A A
+05 hard  spaces between letters: A A
 5 normal spaces between letters: A A
 
 ^--Forced line break
-- 
ffmpeg-codebot

___
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 v3 24/26] doc/APIchanges: update for subtitle filtering changes

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 doc/APIchanges   | 24 
 libavcodec/version.h |  2 +-
 libavutil/version.h  |  2 +-
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 8df0364e4c..c8238fb008 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,30 @@ libavutil: 2021-04-27
 
 API changes, most recent first:
 
+2021-12-05 - xx - lavc 59.15.100 - avcodec.h
+  Deprecate avcodec_encode_subtitle(), use regular encode api now
+
+2021-12-05 - xx - lavc 59.15.100 - codec_desc.h
+  Add avcodec_descriptor_get_subtitle_format()
+
+2021-12-05 - xx - lavc 59.15.100 - avcodec.h
+  Deprecate avsubtitle_free()
+  Deprecate avcodec_decode_subtitle2(), use regular decode api now
+
+2021-12-05 - xx - lavu 57.11.100 - frame.h
+  Add AVMediaType field to AVFrame
+  Add Fields for carrying subtitle data to AVFrame
+  (subtitle_areas, subtitle_header, subtitle_pts, start/end time, etc.)
+  Add av_frame_get_buffer2() and deprecate av_frame_get_buffer()
+
+2021-12-05 - xx - lavu 57.11.100 - subfmt.h
+  Add struct AVSubtitleArea (replaces AVSubtitle)
+  Add av_get_subtitle_fmt_name() and av_get_subtitle_fmt()
+
+2021-12-05 - xx - lavu 57.11.100 - subfmt.h
+  Add enum AVSubtitleType (moved from lavc), add new values, deprecate existing
+
+2021-11-xx - xx - lavfi 8.19.100 - avfilter.h
 2022-01-04 - 78dc21b123e - lavu 57.16.100 - frame.h
   Add AV_FRAME_DATA_DOVI_METADATA.
 
diff --git a/libavcodec/version.h b/libavcodec/version.h
index a46fb05f1a..b5867ad041 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -28,7 +28,7 @@
 #include "libavutil/version.h"
 
 #define LIBAVCODEC_VERSION_MAJOR  59
-#define LIBAVCODEC_VERSION_MINOR  20
+#define LIBAVCODEC_VERSION_MINOR  21
 #define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
diff --git a/libavutil/version.h b/libavutil/version.h
index 5bf48f6304..168e24f410 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,7 +79,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  57
-#define LIBAVUTIL_VERSION_MINOR  18
+#define LIBAVUTIL_VERSION_MINOR  19
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
-- 
ffmpeg-codebot

___
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 v3 25/26] avcodec/webvttenc: Don't encode drawing codes and empty lines

2022-01-19 Thread ffmpegagent
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/webvttenc.c | 31 +++
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/libavcodec/webvttenc.c b/libavcodec/webvttenc.c
index 48945dcb8e..62c4aa7ffd 100644
--- a/libavcodec/webvttenc.c
+++ b/libavcodec/webvttenc.c
@@ -39,6 +39,8 @@ typedef struct {
 int count;
 char stack[WEBVTT_STACK_SIZE];
 int stack_ptr;
+int has_text;
+int drawing_scale;
 } WebVTTContext;
 
 #ifdef __GNUC__
@@ -115,17 +117,24 @@ static void webvtt_style_apply(WebVTTContext *s, const 
char *style)
 static void webvtt_text_cb(void *priv, const char *text, int len)
 {
 WebVTTContext *s = priv;
-av_bprint_append_data(&s->buffer, text, len);
+if (!s->drawing_scale) {
+av_bprint_append_data(&s->buffer, text, len);
+s->has_text = 1;
+}
 }
 
 static void webvtt_new_line_cb(void *priv, int forced)
 {
-webvtt_print(priv, "\n");
+WebVTTContext *s = priv;
+if (!s->drawing_scale)
+webvtt_print(priv, "\n");
 }
 
 static void webvtt_hard_space_cb(void *priv)
 {
-webvtt_print(priv, " ");
+WebVTTContext *s = priv;
+if (!s->drawing_scale)
+webvtt_print(priv, " ");
 }
 
 static void webvtt_style_cb(void *priv, char style, int close)
@@ -149,6 +158,12 @@ static void webvtt_end_cb(void *priv)
 webvtt_stack_push_pop(priv, 0, 1);
 }
 
+static void dialog_drawing_mode_cb(void *priv, int scale)
+{
+WebVTTContext *s = priv;
+s->drawing_scale = scale;
+}
+
 static const ASSCodesCallbacks webvtt_callbacks = {
 .text = webvtt_text_cb,
 .new_line = webvtt_new_line_cb,
@@ -161,6 +176,7 @@ static const ASSCodesCallbacks webvtt_callbacks = {
 .cancel_overrides = webvtt_cancel_overrides_cb,
 .move = NULL,
 .end  = webvtt_end_cb,
+.drawing_mode = dialog_drawing_mode_cb,
 };
 
 static void ensure_ass_context(WebVTTContext* s, const AVFrame* frame)
@@ -211,16 +227,23 @@ static int webvtt_encode_frame(AVCodecContext* avctx, 
AVPacket* avpkt,
 }
 
 if (ass) {
+const unsigned saved_len = s->buffer.len;
 
-if (i > 0)
+if (i > 0 && s->buffer.len > 0)
 webvtt_new_line_cb(s, 0);
 
+s->drawing_scale = 0;
+s->has_text = 0;
+
 dialog = avpriv_ass_split_dialog(s->ass_ctx, ass);
 if (!dialog)
 return AVERROR(ENOMEM);
 webvtt_style_apply(s, dialog->style);
 avpriv_ass_split_override_codes(&webvtt_callbacks, s, 
dialog->text);
 avpriv_ass_free_dialog(&dialog);
+
+if (!s->has_text)
+s->buffer.len = saved_len;
 }
 }
 
-- 
ffmpeg-codebot

___
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 v3 26/26] avcodec/dvbsubdec: Fix conditions for fallback to default resolution

2022-01-19 Thread ffmpegagent
From: softworkz 

The previous code expected a segment of type CLUT definition to exist
in order to accept a set of segments to be complete.
This was an incorrect assumption as the presence of a CLUT segment
is not mandatory.
(version 1.6.1 of the spec is probably a bit more clear about this
than earlier versions: https://www.etsi.org/deliver/etsi_en/
300700_300799/300743/01.06.01_20/en_300743v010601a.pdf)

The flawed condition prevented proper fallback to using the default
resolution for the decoding context.

Signed-off-by: softworkz 
---
 libavcodec/dvbsubdec.c | 51 +-
 1 file changed, 30 insertions(+), 21 deletions(-)

diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c
index 0d64c6e71c..3a6259101c 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -33,7 +33,7 @@
 #define DVBSUB_CLUT_SEGMENT 0x12
 #define DVBSUB_OBJECT_SEGMENT   0x13
 #define DVBSUB_DISPLAYDEFINITION_SEGMENT 0x14
-#define DVBSUB_DISPLAY_SEGMENT  0x80
+#define DVBSUB_END_DISPLAY_SEGMENT  0x80
 
 #define cm (ff_crop_tab + MAX_NEG_CROP)
 
@@ -1620,8 +1620,12 @@ static int dvbsub_decode(AVCodecContext *avctx,
 int segment_length;
 int i;
 int ret = 0;
-int got_segment = 0;
-int got_dds = 0;
+//int got_segment = 0;
+int got_page = 0;
+int got_region = 0;
+int got_object = 0;
+int got_end_display = 0;
+int got_displaydef = 0;
 
 ff_dlog(avctx, "DVB sub packet:\n");
 
@@ -1666,34 +1670,28 @@ static int dvbsub_decode(AVCodecContext *avctx,
 switch (segment_type) {
 case DVBSUB_PAGE_SEGMENT:
 ret = dvbsub_parse_page_segment(avctx, p, segment_length, sub, 
got_sub_ptr);
-got_segment |= 1;
+got_page = 1;
 break;
 case DVBSUB_REGION_SEGMENT:
 ret = dvbsub_parse_region_segment(avctx, p, segment_length);
-got_segment |= 2;
+got_region = 1;
 break;
 case DVBSUB_CLUT_SEGMENT:
 ret = dvbsub_parse_clut_segment(avctx, p, segment_length);
 if (ret < 0) goto end;
-got_segment |= 4;
 break;
 case DVBSUB_OBJECT_SEGMENT:
 ret = dvbsub_parse_object_segment(avctx, p, segment_length);
-got_segment |= 8;
+got_object = 1;
 break;
 case DVBSUB_DISPLAYDEFINITION_SEGMENT:
 ret = dvbsub_parse_display_definition_segment(avctx, p,
   segment_length);
-got_dds = 1;
+got_displaydef = 1;
 break;
-case DVBSUB_DISPLAY_SEGMENT:
+case DVBSUB_END_DISPLAY_SEGMENT:
 ret = dvbsub_display_end_segment(avctx, p, segment_length, 
sub, got_sub_ptr);
-if (got_segment == 15 && !got_dds && !avctx->width && 
!avctx->height) {
-// Default from ETSI EN 300 743 V1.3.1 (7.2.1)
-avctx->width  = 720;
-avctx->height = 576;
-}
-got_segment |= 16;
+got_end_display = 1;
 break;
 default:
 ff_dlog(avctx, "Subtitling segment type 0x%x, page id %d, 
length %d\n",
@@ -1706,13 +1704,24 @@ static int dvbsub_decode(AVCodecContext *avctx,
 
 p += segment_length;
 }
-// Some streams do not send a display segment but if we have all the other
-// segments then we need no further data.
-if (got_segment == 15) {
-av_log(avctx, AV_LOG_DEBUG, "Missing display_end_segment, 
emulating\n");
-dvbsub_display_end_segment(avctx, p, 0, sub, got_sub_ptr);
-}
 
+// Even though not mandated by the spec, we're imposing a minimum 
requirement
+// for a useful packet to have at least one page, region and object 
segment.
+if (got_page && got_region && got_object && got_end_display) {
+
+if (!got_displaydef && !avctx->width && !avctx->height) {
+// Default from ETSI EN 300 743 V1.3.1 (7.2.1)
+avctx->width  = 720;
+avctx->height = 576;
+}
+
+// Some streams do not send an end-of-display segment but if we have 
all the other
+// segments then we need no further data.
+if (!got_end_display) {
+av_log(avctx, AV_LOG_DEBUG, "Missing display_end_segment, 
emulating\n");
+dvbsub_display_end_segment(avctx, p, 0, sub, got_sub_ptr);
+}
+}
 end:
 if (ret < 0) {
 return ret;
-- 
ffmpeg-codebot
___
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] libavcodec/qsvenc: fix a memory leak problem

2022-01-19 Thread Wenbin Chen
"qf->frame" ref to input frame but it isn't released. av_frame_unref()
is added before refering qf->frame to new frame to make sure the previous
reference is released.

Signed-off-by: Wenbin Chen 
---
 libavcodec/qsvenc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 269386624d..fd5c460d68 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -1521,6 +1521,7 @@ static int submit_frame(QSVEncContext *q, const AVFrame 
*frame,
 return ret;
 }
 } else {
+av_frame_unref(qf->frame);
 ret = av_frame_ref(qf->frame, frame);
 if (ret < 0)
 return ret;
-- 
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".


  1   2   >