[FFmpeg-devel] [PATCH v2 2/2] avfilter/vpp_qsv: Copy side-data from input to output frame

2022-11-03 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/qsvvpp.c |  6 ++
 libavfilter/vf_overlay_qsv.c | 19 +++
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
index 8428ee89ab..ae9766d12f 100644
--- a/libavfilter/qsvvpp.c
+++ b/libavfilter/qsvvpp.c
@@ -880,6 +880,12 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink 
*inlink, AVFrame *picr
 return AVERROR(EAGAIN);
 break;
 }
+
+av_frame_remove_all_side_data(out_frame->frame);
+ret = av_frame_copy_side_data(out_frame->frame, in_frame->frame, 0);
+if (ret < 0)
+return ret;
+
 out_frame->frame->pts = av_rescale_q(out_frame->surface.Data.TimeStamp,
  default_tb, outlink->time_base);
 
diff --git a/libavfilter/vf_overlay_qsv.c b/libavfilter/vf_overlay_qsv.c
index d947a1faa1..04fd284b92 100644
--- a/libavfilter/vf_overlay_qsv.c
+++ b/libavfilter/vf_overlay_qsv.c
@@ -231,13 +231,24 @@ static int process_frame(FFFrameSync *fs)
 {
 AVFilterContext  *ctx = fs->parent;
 QSVOverlayContext  *s = fs->opaque;
+AVFrame   *frame0 = NULL;
 AVFrame*frame = NULL;
-int   ret = 0, i;
+int   ret = 0;
 
-for (i = 0; i < ctx->nb_inputs; i++) {
+for (unsigned i = 0; i < ctx->nb_inputs; i++) {
 ret = ff_framesync_get_frame(fs, i, , 0);
-if (ret == 0)
-ret = ff_qsvvpp_filter_frame(s->qsv, ctx->inputs[i], frame);
+
+if (ret == 0) {
+if (i == 0)
+frame0 = frame;
+else {
+av_frame_remove_all_side_data(frame);
+ret = av_frame_copy_side_data(frame, frame0, 0);
+}
+
+ret = ret < 0 ? ret : ff_qsvvpp_filter_frame(s->qsv, 
ctx->inputs[i], frame);
+}
+
 if (ret < 0 && ret != AVERROR(EAGAIN))
 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 1/2] avutil/frame: Add av_frame_copy_side_data() and av_frame_remove_all_side_data()

2022-11-03 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
Signed-off-by: Anton Khirnov 
---
 doc/APIchanges  |  4 +++
 libavutil/frame.c   | 67 +++--
 libavutil/frame.h   | 32 ++
 libavutil/version.h |  2 +-
 4 files changed, 78 insertions(+), 27 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 3c86f24285..e88cf7b4aa 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,10 @@ libavutil: 2021-04-27
 
 API changes, most recent first:
 
+2022-05-26 - x - lavu 57.41.100 - frame.h
+  Add av_frame_remove_all_side_data(), av_frame_copy_side_data(),
+  AV_FRAME_TRANSFER_SD_COPY, and AV_FRAME_TRANSFER_SD_FILTER.
+  
 2022-10-30 - xx - lavu 57.40.100 - channel_layout.h
   Add AV_CH_LAYOUT_CUBE and AV_CHANNEL_LAYOUT_CUBE.
 
diff --git a/libavutil/frame.c b/libavutil/frame.c
index de4ad1f94d..8eb0e1ec95 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -276,9 +276,45 @@ FF_ENABLE_DEPRECATION_WARNINGS
 return AVERROR(EINVAL);
 }
 
+void av_frame_remove_all_side_data(AVFrame *frame)
+{
+wipe_side_data(frame);
+}
+
+int av_frame_copy_side_data(AVFrame* dst, const AVFrame* src, int flags)
+{
+for (unsigned i = 0; i < src->nb_side_data; i++) {
+const AVFrameSideData *sd_src = src->side_data[i];
+AVFrameSideData *sd_dst;
+if ((flags & AV_FRAME_TRANSFER_SD_FILTER) &&
+sd_src->type == AV_FRAME_DATA_PANSCAN &&
+(src->width != dst->width || src->height != dst->height))
+continue;
+if (flags & AV_FRAME_TRANSFER_SD_COPY) {
+sd_dst = av_frame_new_side_data(dst, sd_src->type,
+sd_src->size);
+if (!sd_dst) {
+wipe_side_data(dst);
+return AVERROR(ENOMEM);
+}
+memcpy(sd_dst->data, sd_src->data, sd_src->size);
+} else {
+AVBufferRef *ref = av_buffer_ref(sd_src->buf);
+sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref);
+if (!sd_dst) {
+av_buffer_unref();
+wipe_side_data(dst);
+return AVERROR(ENOMEM);
+}
+}
+av_dict_copy(_dst->metadata, sd_src->metadata, 0);
+}
+return 0;
+}
+
 static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy)
 {
-int ret, i;
+int ret;
 
 dst->key_frame  = src->key_frame;
 dst->pict_type  = src->pict_type;
@@ -319,31 +355,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
 av_dict_copy(>metadata, src->metadata, 0);
 
-for (i = 0; i < src->nb_side_data; i++) {
-const AVFrameSideData *sd_src = src->side_data[i];
-AVFrameSideData *sd_dst;
-if (   sd_src->type == AV_FRAME_DATA_PANSCAN
-&& (src->width != dst->width || src->height != dst->height))
-continue;
-if (force_copy) {
-sd_dst = av_frame_new_side_data(dst, sd_src->type,
-sd_src->size);
-if (!sd_dst) {
-wipe_side_data(dst);
-return AVERROR(ENOMEM);
-}
-memcpy(sd_dst->data, sd_src->data, sd_src->size);
-} else {
-AVBufferRef *ref = av_buffer_ref(sd_src->buf);
-sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref);
-if (!sd_dst) {
-av_buffer_unref();
-wipe_side_data(dst);
-return AVERROR(ENOMEM);
-}
-}
-av_dict_copy(_dst->metadata, sd_src->metadata, 0);
-}
+if ((ret = av_frame_copy_side_data(dst, src,
+(force_copy ? AV_FRAME_TRANSFER_SD_COPY : 0) |
+AV_FRAME_TRANSFER_SD_FILTER) < 0))
+return ret;
 
 ret = av_buffer_replace(>opaque_ref, src->opaque_ref);
 ret |= av_buffer_replace(>private_ref, src->private_ref);
diff --git a/libavutil/frame.h b/libavutil/frame.h
index e60a82f6c0..5a3362fb55 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -861,6 +861,30 @@ int av_frame_copy(AVFrame *dst, const AVFrame *src);
  */
 int av_frame_copy_props(AVFrame *dst, const AVFrame *src);
 
+
+/**
+ * Copy side data, rather than creating new references.
+ */
+#define AV_FRAME_TRANSFER_SD_COPY  (1 << 0)
+/**
+ * Filter out side data that does not match dst properties.
+ */
+#define AV_FRAME_TRANSFER_SD_FILTER(1 << 1)
+
+/**
+ * Copy all side-data from src to dst.
+ *
+ * @param dst a frame to which the side data should be copied.
+ * @param src a frame from which to copy the side data.
+ * @param flags a combination of AV_FRAME_TRANSFER_SD_*
+ *
+ * @return 0 on success, a negative AVERROR on error.
+ *
+ * @note This function will create

[FFmpeg-devel] [PATCH v2 04/11] avfilter/overlay_vaapi: handle secondary null input

2022-10-31 Thread softworkz
From: softworkz 

Currently segfaults in this case.

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 94 ++
 1 file changed, 49 insertions(+), 45 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index 66e736cce4..1281038c36 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -106,18 +106,6 @@ static int overlay_vaapi_render_picture(AVFilterContext 
*avctx,
params_id);
 
 
-vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
- VAProcPipelineParameterBufferType,
- sizeof(*subpic_params), 1, subpic_params, 
_params_id);
-if (vas != VA_STATUS_SUCCESS) {
-av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: "
-   "%d (%s).\n", vas, vaErrorStr(vas));
-err = AVERROR(EIO);
-goto fail_after_begin;
-}
-av_log(avctx, AV_LOG_DEBUG, "Pipeline subpic parameter buffer is %#x.\n",
-   subpic_params_id);
-
 vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
   _id, 1);
 if (vas != VA_STATUS_SUCCESS) {
@@ -127,13 +115,27 @@ static int overlay_vaapi_render_picture(AVFilterContext 
*avctx,
 goto fail_after_begin;
 }
 
-vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
-  _params_id, 1);
-if (vas != VA_STATUS_SUCCESS) {
-av_log(avctx, AV_LOG_ERROR, "Failed to render subpic parameter buffer: 
"
-   "%d (%s).\n", vas, vaErrorStr(vas));
-err = AVERROR(EIO);
-goto fail_after_begin;
+if (subpic_params) {
+vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
+ VAProcPipelineParameterBufferType,
+ sizeof(*subpic_params), 1, subpic_params, 
_params_id);
+if (vas != VA_STATUS_SUCCESS) {
+av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: "
+   "%d (%s).\n", vas, vaErrorStr(vas));
+err = AVERROR(EIO);
+goto fail_after_begin;
+}
+av_log(avctx, AV_LOG_DEBUG, "Pipeline subpic parameter buffer is 
%#x.\n",
+   subpic_params_id);
+
+vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
+  _params_id, 1);
+if (vas != VA_STATUS_SUCCESS) {
+av_log(avctx, AV_LOG_ERROR, "Failed to render subpic parameter 
buffer: "
+   "%d (%s).\n", vas, vaErrorStr(vas));
+err = AVERROR(EIO);
+goto fail_after_begin;
+}
 }
 
 vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
@@ -177,7 +179,7 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
 AVFrame *input_main, *input_overlay;
 AVFrame *output;
 VAProcPipelineParameterBuffer params, subpic_params;
-VABlendState blend_state; /**< Blend State */
+VABlendState blend_state = { 0 }; /**< Blend State */
 VARectangle overlay_region, output_region;
 int err;
 
@@ -192,10 +194,6 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
av_get_pix_fmt_name(input_main->format),
input_main->width, input_main->height, input_main->pts);
 
-av_log(avctx, AV_LOG_DEBUG, "Filter overlay: %s, %ux%u (%"PRId64").\n",
-   av_get_pix_fmt_name(input_overlay->format),
-   input_overlay->width, input_overlay->height, input_overlay->pts);
-
 if (vpp_ctx->va_context == VA_INVALID_ID)
 return AVERROR(EINVAL);
 
@@ -214,13 +212,6 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
 if (err < 0)
 goto fail;
 
-overlay_region = (VARectangle) {
-.x  = ctx->overlay_ox,
-.y  = ctx->overlay_oy,
-.width  = ctx->overlay_ow ? ctx->overlay_ow : input_overlay->width,
-.height = ctx->overlay_oh ? ctx->overlay_oh : input_overlay->height,
-};
-
 output_region = (VARectangle) {
 .x  = 0,
 .y  = 0,
@@ -228,29 +219,42 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
 .height = output->height,
 };
 
-if (overlay_region.x + overlay_region.width > input_main->width ||
-overlay_region.y + overlay_region.height > input_main->height) {
-av_log(ctx, AV_LOG_WARNING,
-   "The overlay image exceeds the scope of the main image, "
-   "will crop the overlay image according based on the main 
image.\n");
-}
-
 params.filters = _ctx->filter_buffers[0];
 params.num_filters = vpp_ctx->nb_filter_buffers;
 
 params.output_region = _region;
 params.output_background_color = VAAPI

[FFmpeg-devel] [PATCH v2 11/11] doc/filters.texi: update overlay_vaapi documentation

2022-10-31 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 doc/filters.texi | 51 +---
 1 file changed, 40 insertions(+), 11 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 2d0b5db909..1d50db0e54 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -26271,30 +26271,59 @@ It takes two inputs and has one output. The first 
input is the "main" video on w
 The filter accepts the following options:
 
 @table @option
-
 @item x
-Set the x coordinate of the overlaid video on the main video.
-Default value is @code{0}.
-
 @item y
-Set the y coordinate of the overlaid video on the main video.
-Default value is @code{0}.
+Set expressions for the x and y coordinates of the overlaid video
+on the main video.
 
-@item w
-Set the width of the overlaid video on the main video.
-Default value is the width of input overlay video.
+Default value is "0" for both expressions.
 
+@item w
 @item h
-Set the height of the overlaid video on the main video.
-Default value is the height of input overlay video.
+Set expressions for the width and height the overlaid video
+on the main video.
+
+Default values are 'overlay_iw' for 'w' and 'overlay_ih*w/overlay_iw' for 'h'.
+
+The expressions can contain the following parameters:
+
+@table @option
+
+@item main_w, W
+@item main_h, H
+The main input width and height.
+
+@item overlay_iw
+@item overlay_ih
+The overlay input width and height.
+
+@item overlay_w, w
+@item overlay_h, h
+The overlay output width and height.
+
+@item overlay_x, x
+@item overlay_y, y
+Position of the overlay layer inside of main
+
+@end table
 
 @item alpha
 Set transparency of overlaid video. Allowed range is 0.0 to 1.0.
 Higher value means lower transparency.
 Default value is @code{1.0}.
 
+@item eof_action
+See @ref{framesync}.
+
+@item shortest
+See @ref{framesync}.
+
+@item repeatlast
+See @ref{framesync}.
+
 @end table
 
+This filter also supports the @ref{framesync} options.
 @subsection Examples
 
 @itemize
-- 
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/11] doc/filters.texi: remove incorrect statement

2022-10-31 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 doc/filters.texi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 68205147f0..2d0b5db909 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -26267,7 +26267,6 @@ To use vaapi filters, you need to setup the vaapi 
device correctly. For more inf
 Overlay one video on the top of another.
 
 It takes two inputs and has one output. The first input is the "main" video on 
which the second input is overlaid.
-This filter requires same memory layout for all the inputs. So, format 
conversion may be needed.
 
 The filter accepts the following options:
 
-- 
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 02/11] avfilter/overlay_vaapi: build filter params just once

2022-10-31 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index 218daf571f..cf17426b5d 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -181,10 +181,6 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
 VARectangle overlay_region, output_region;
 int err;
 
-err = overlay_vaapi_build_filter_params(avctx);
-if (err < 0)
-return err;
-
 err = ff_framesync_get_frame(fs, 0, _main, 0);
 if (err < 0)
 return err;
@@ -309,6 +305,10 @@ static int overlay_vaapi_config_output(AVFilterLink 
*outlink)
 if (err < 0)
 return err;
 
+err = overlay_vaapi_build_filter_params(avctx);
+if (err < 0)
+return err;
+
 err = ff_framesync_init_dualinput(>fs, avctx);
 if (err < 0)
 return err;
-- 
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 09/11] avfilter/overlay_vaapi: enable expressions for overlay parameters

2022-10-31 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 141 +
 1 file changed, 127 insertions(+), 14 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index b2c254d9dd..307f3cf7fc 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -27,19 +27,106 @@
 #include "formats.h"
 #include "internal.h"
 #include "vaapi_vpp.h"
+#include "libavutil/eval.h"
+
+enum var_name {
+VAR_MAIN_IW, VAR_MW,
+VAR_MAIN_IH, VAR_MH,
+VAR_OVERLAY_IW,
+VAR_OVERLAY_IH,
+VAR_OVERLAY_X,  VAR_OX,
+VAR_OVERLAY_Y,  VAR_OY,
+VAR_OVERLAY_W,  VAR_OW,
+VAR_OVERLAY_H,  VAR_OH,
+VAR_VARS_NB
+};
 
 typedef struct OverlayVAAPIContext {
 VAAPIVPPContext  vpp_ctx; /**< must be the first field */
 FFFrameSync  fs;
-int  overlay_ox;
-int  overlay_oy;
-int  overlay_ow;
-int  overlay_oh;
+
+double   var_values[VAR_VARS_NB];
+char *overlay_ox;
+char *overlay_oy;
+char *overlay_ow;
+char *overlay_oh;
+int  ox;
+int  oy;
+int  ow;
+int  oh;
 floatalpha;
 unsigned int blend_flags;
 floatblend_alpha;
 } OverlayVAAPIContext;
 
+static const char *const var_names[] = {
+"main_w", "W",   /* input width of the main layer */
+"main_h", "H",   /* input height of the main layer */
+"overlay_iw",/* input width of the overlay layer */
+"overlay_ih",/* input height of the overlay layer */
+"overlay_x",  "x",   /* x position of the overlay layer inside of main */
+"overlay_y",  "y",   /* y position of the overlay layer inside of main */
+"overlay_w",  "w",   /* output width of overlay layer */
+"overlay_h",  "h",   /* output height of overlay layer */
+NULL
+};
+
+static int eval_expr(AVFilterContext *avctx)
+{
+OverlayVAAPIContext *ctx = avctx->priv;
+double   *var_values = ctx->var_values;
+int  ret = 0;
+AVExpr *ox_expr = NULL, *oy_expr = NULL;
+AVExpr *ow_expr = NULL, *oh_expr = NULL;
+
+#define PARSE_EXPR(e, s) {\
+ret = av_expr_parse(&(e), s, var_names, NULL, NULL, NULL, NULL, 0, ctx); \
+if (ret < 0) {\
+av_log(ctx, AV_LOG_ERROR, "Error when parsing '%s'.\n", s);\
+goto release;\
+}\
+}
+PARSE_EXPR(ox_expr, ctx->overlay_ox)
+PARSE_EXPR(oy_expr, ctx->overlay_oy)
+PARSE_EXPR(ow_expr, ctx->overlay_ow)
+PARSE_EXPR(oh_expr, ctx->overlay_oh)
+#undef PASS_EXPR
+
+var_values[VAR_OVERLAY_W] =
+var_values[VAR_OW]= av_expr_eval(ow_expr, var_values, NULL);
+var_values[VAR_OVERLAY_H] =
+var_values[VAR_OH]= av_expr_eval(oh_expr, var_values, NULL);
+
+/* calc again in case ow is relative to oh */
+var_values[VAR_OVERLAY_W] =
+var_values[VAR_OW]= av_expr_eval(ow_expr, var_values, NULL);
+
+var_values[VAR_OVERLAY_X] =
+var_values[VAR_OX]= av_expr_eval(ox_expr, var_values, NULL);
+var_values[VAR_OVERLAY_Y] =
+var_values[VAR_OY]= av_expr_eval(oy_expr, var_values, NULL);
+
+/* calc again in case ox is relative to oy */
+var_values[VAR_OVERLAY_X] =
+var_values[VAR_OX]= av_expr_eval(ox_expr, var_values, NULL);
+
+/* calc overlay_w and overlay_h again incase relative to ox,oy */
+var_values[VAR_OVERLAY_W] =
+var_values[VAR_OW]= av_expr_eval(ow_expr, var_values, NULL);
+var_values[VAR_OVERLAY_H] =
+var_values[VAR_OH]= av_expr_eval(oh_expr, var_values, NULL);
+var_values[VAR_OVERLAY_W] =
+var_values[VAR_OW]= av_expr_eval(ow_expr, var_values, NULL);
+
+release:
+av_expr_free(ox_expr);
+av_expr_free(oy_expr);
+av_expr_free(ow_expr);
+av_expr_free(oh_expr);
+
+return ret;
+}
+
 static int overlay_vaapi_build_filter_params(AVFilterContext *avctx)
 {
 VAAPIVPPContext *vpp_ctx   = avctx->priv;
@@ -233,10 +320,10 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
input_overlay->width, input_overlay->height, 
input_overlay->pts);
 
 overlay_region = (VARectangle) {
-.x  = ctx->overlay_ox,
-.y  = ctx->overlay_oy,
-.width  = ctx->overlay_ow ? ctx->overlay_ow : input_overlay->width,
-.height = ctx->overlay_oh ? ctx->overlay_oh : 
input_overlay->height,
+.x  = ctx->ox,
+.y  = ctx->oy,
+.width  = ctx->ow ? ctx->ow : input_overlay->width,
+.height = ctx-

[FFmpeg-devel] [PATCH v2 01/11] avfilter/overlay_vaapi: use FILTER_SINGLE_PIXFMT

2022-10-31 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 30 +-
 1 file changed, 1 insertion(+), 29 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index 3e6a0de13f..218daf571f 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -38,34 +38,6 @@ typedef struct OverlayVAAPIContext {
 floatalpha;
 } OverlayVAAPIContext;
 
-static int overlay_vaapi_query_formats(AVFilterContext *ctx)
-{
-int ret;
-enum {
-MAIN= 0,
-OVERLAY = 1,
-};
-
-static const enum AVPixelFormat pix_fmts[] = {
-AV_PIX_FMT_VAAPI,
-AV_PIX_FMT_NONE
-};
-
-ret = ff_formats_ref(ff_make_format_list(pix_fmts), 
>inputs[MAIN]->outcfg.formats);
-if (ret < 0)
-return ret;
-
-ret = ff_formats_ref(ff_make_format_list(pix_fmts), 
>inputs[OVERLAY]->outcfg.formats);
-if (ret < 0)
-return ret;
-
-ret = ff_formats_ref(ff_make_format_list(pix_fmts), 
>outputs[0]->incfg.formats);
-if (ret < 0)
-return ret;
-
-return 0;
-}
-
 static int overlay_vaapi_build_filter_params(AVFilterContext *avctx)
 {
 VAAPIVPPContext *vpp_ctx   = avctx->priv;
@@ -418,6 +390,6 @@ const AVFilter ff_vf_overlay_vaapi = {
 .activate= _vaapi_activate,
 FILTER_INPUTS(overlay_vaapi_inputs),
 FILTER_OUTPUTS(overlay_vaapi_outputs),
-FILTER_QUERY_FUNC(overlay_vaapi_query_formats),
+FILTER_SINGLE_PIXFMT(AV_PIX_FMT_VAAPI),
 .flags_internal  = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
-- 
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 08/11] avfilter/overlay_vaapi: precalculate blend_state, enable pixel alpha

2022-10-31 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 44 --
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index f4f9cc58ec..b2c254d9dd 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -36,6 +36,8 @@ typedef struct OverlayVAAPIContext {
 int  overlay_ow;
 int  overlay_oh;
 floatalpha;
+unsigned int blend_flags;
+floatblend_alpha;
 } OverlayVAAPIContext;
 
 static int overlay_vaapi_build_filter_params(AVFilterContext *avctx)
@@ -246,8 +248,8 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
 
 memcpy(_params, , sizeof(subpic_params));
 
-blend_state.flags = VA_BLEND_GLOBAL_ALPHA;
-blend_state.global_alpha  = ctx->alpha;
+blend_state.flags = ctx->blend_flags;
+blend_state.global_alpha  = ctx->blend_alpha;
 subpic_params.blend_state = _state;
 
 subpic_params.surface   = 
(VASurfaceID)(uintptr_t)input_overlay->data[3];
@@ -269,6 +271,43 @@ fail:
 return err;
 }
 
+static int have_alpha_planar(AVFilterLink *link)
+{
+enum AVPixelFormat pix_fmt = link->format;
+const AVPixFmtDescriptor *desc;
+AVHWFramesContext *fctx;
+
+if (link->format == AV_PIX_FMT_VAAPI) {
+fctx= (AVHWFramesContext *)link->hw_frames_ctx->data;
+pix_fmt = fctx->sw_format;
+}
+
+desc = av_pix_fmt_desc_get(pix_fmt);
+if (!desc)
+return 0;
+
+return !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA);
+}
+
+static int overlay_vaapi_config_input_overlay(AVFilterLink *inlink)
+{
+AVFilterContext  *avctx  = inlink->dst;
+OverlayVAAPIContext *ctx = avctx->priv;
+
+ctx->blend_flags = 0;
+ctx->blend_alpha = 1.0f;
+
+if (ctx->alpha < 1.0f) {
+ctx->blend_flags |= VA_BLEND_GLOBAL_ALPHA;
+ctx->blend_alpha  = ctx->alpha;
+}
+
+if (have_alpha_planar(inlink))
+ctx->blend_flags |= VA_BLEND_PREMULTIPLIED_ALPHA;
+
+return 0;
+}
+
 static int overlay_vaapi_config_output(AVFilterLink *outlink)
 {
 AVFilterContext  *avctx  = outlink->src;
@@ -353,6 +392,7 @@ static const AVFilterPad overlay_vaapi_inputs[] = {
 {
 .name = "overlay",
 .type = AVMEDIA_TYPE_VIDEO,
+.config_props = overlay_vaapi_config_input_overlay,
 },
 };
 
-- 
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 07/11] avfilter/overlay_vaapi: add framesync options

2022-10-31 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index 71fc90a86b..f4f9cc58ec 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -292,8 +292,7 @@ static int overlay_vaapi_config_output(AVFilterLink 
*outlink)
 if (err < 0)
 return err;
 
-ctx->fs.on_event  = overlay_vaapi_blend;
-ctx->fs.opaque= ctx;
+ctx->fs.on_event = overlay_vaapi_blend;
 ctx->fs.time_base = outlink->time_base;
 
 return ff_framesync_configure(>fs);
@@ -321,6 +320,7 @@ static av_cold void overlay_vaapi_uninit(AVFilterContext 
*avctx)
 OverlayVAAPIContext *ctx = avctx->priv;
 
 ff_framesync_uninit(>fs);
+ff_vaapi_vpp_ctx_uninit(avctx);
 }
 
 #define OFFSET(x) offsetof(OverlayVAAPIContext, x)
@@ -331,10 +331,18 @@ static const AVOption overlay_vaapi_options[] = {
 { "w", "Overlay width",OFFSET(overlay_ow), AV_OPT_TYPE_INT,   
{ .i64 = 0 },   0, INT_MAX, .flags = FLAGS },
 { "h", "Overlay height",   OFFSET(overlay_oh), AV_OPT_TYPE_INT,   
{ .i64 = 0 },   0, INT_MAX, .flags = FLAGS },
 { "alpha", "Overlay global alpha", OFFSET(alpha),  AV_OPT_TYPE_FLOAT, 
{ .dbl = 1.0 }, 0.0, 1.0,   .flags = FLAGS },
+{ "eof_action", "Action to take when encountering EOF from secondary input 
",
+OFFSET(fs.opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT 
},
+EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, "eof_action" },
+{ "repeat", "Repeat the previous frame.",   0, AV_OPT_TYPE_CONST, { 
.i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, "eof_action" },
+{ "endall", "End both streams.",0, AV_OPT_TYPE_CONST, { 
.i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, "eof_action" },
+{ "pass",   "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { 
.i64 = EOF_ACTION_PASS },   .flags = FLAGS, "eof_action" },
+{ "shortest", "force termination when the shortest input terminates", 
OFFSET(fs.opt_shortest),   AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
+{ "repeatlast", "repeat overlay of the last overlay frame",   
OFFSET(fs.opt_repeatlast), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS },
 { NULL },
 };
 
-AVFILTER_DEFINE_CLASS(overlay_vaapi);
+FRAMESYNC_DEFINE_CLASS(overlay_vaapi, OverlayVAAPIContext, fs);
 
 static const AVFilterPad overlay_vaapi_inputs[] = {
 {
@@ -364,6 +372,7 @@ const AVFilter ff_vf_overlay_vaapi = {
 .init= _vaapi_init,
 .uninit  = _vaapi_uninit,
 .activate= _vaapi_activate,
+.preinit = overlay_vaapi_framesync_preinit,
 FILTER_INPUTS(overlay_vaapi_inputs),
 FILTER_OUTPUTS(overlay_vaapi_outputs),
 FILTER_SINGLE_PIXFMT(AV_PIX_FMT_VAAPI),
-- 
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/11] avfilter/overlay_vaapi: remove redundant .get_buffer assignments

2022-10-31 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index c14aacbb5d..71fc90a86b 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -340,13 +340,11 @@ static const AVFilterPad overlay_vaapi_inputs[] = {
 {
 .name = "main",
 .type = AVMEDIA_TYPE_VIDEO,
-.get_buffer.video = ff_default_get_video_buffer,
 .config_props = _vaapi_vpp_config_input,
 },
 {
 .name = "overlay",
 .type = AVMEDIA_TYPE_VIDEO,
-.get_buffer.video = ff_default_get_video_buffer,
 },
 };
 
-- 
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/11] avfilter/overlay_vaapi: reformat options

2022-10-31 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 15 +--
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index 1281038c36..c14aacbb5d 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -326,16 +326,11 @@ static av_cold void overlay_vaapi_uninit(AVFilterContext 
*avctx)
 #define OFFSET(x) offsetof(OverlayVAAPIContext, x)
 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
 static const AVOption overlay_vaapi_options[] = {
-{ "x", "Overlay x position",
-  OFFSET(overlay_ox), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = 
FLAGS },
-{ "y", "Overlay y position",
-  OFFSET(overlay_oy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = 
FLAGS },
-{ "w", "Overlay width",
-  OFFSET(overlay_ow), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = 
FLAGS },
-{ "h", "Overlay height",
-  OFFSET(overlay_oh), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = 
FLAGS },
-{ "alpha", "Overlay global alpha",
-  OFFSET(alpha), AV_OPT_TYPE_FLOAT, { .dbl = 1.0}, 0.0, 1.0, .flags = 
FLAGS},
+{ "x", "Overlay x position",   OFFSET(overlay_ox), AV_OPT_TYPE_INT,   
{ .i64 = 0 },   0, INT_MAX, .flags = FLAGS },
+{ "y", "Overlay y position",   OFFSET(overlay_oy), AV_OPT_TYPE_INT,   
{ .i64 = 0 },   0, INT_MAX, .flags = FLAGS },
+{ "w", "Overlay width",OFFSET(overlay_ow), AV_OPT_TYPE_INT,   
{ .i64 = 0 },   0, INT_MAX, .flags = FLAGS },
+{ "h", "Overlay height",   OFFSET(overlay_oh), AV_OPT_TYPE_INT,   
{ .i64 = 0 },   0, INT_MAX, .flags = FLAGS },
+{ "alpha", "Overlay global alpha", OFFSET(alpha),  AV_OPT_TYPE_FLOAT, 
{ .dbl = 1.0 }, 0.0, 1.0,   .flags = FLAGS },
 { NULL },
 };
 
-- 
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 03/11] avfilter/overlay_vaapi: remove double framesync init

2022-10-31 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 31 +--
 1 file changed, 5 insertions(+), 26 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index cf17426b5d..66e736cce4 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -265,28 +265,6 @@ fail:
 return err;
 }
 
-static int overlay_vaapi_init_framesync(AVFilterContext *avctx)
-{
-OverlayVAAPIContext *ctx = avctx->priv;
-int ret, i;
-
-ctx->fs.on_event = overlay_vaapi_blend;
-ctx->fs.opaque   = ctx;
-ret = ff_framesync_init(>fs, avctx, avctx->nb_inputs);
-if (ret < 0)
-return ret;
-
-for (i = 0; i < avctx->nb_inputs; i++) {
-FFFrameSyncIn *in = >fs.in[i];
-in->before= EXT_STOP;
-in->after = EXT_INFINITY;
-in->sync  = i ? 1 : 2;
-in->time_base = avctx->inputs[i]->time_base;
-}
-
-return ff_framesync_configure(>fs);
-}
-
 static int overlay_vaapi_config_output(AVFilterLink *outlink)
 {
 AVFilterContext  *avctx  = outlink->src;
@@ -294,10 +272,7 @@ static int overlay_vaapi_config_output(AVFilterLink 
*outlink)
 VAAPIVPPContext *vpp_ctx = avctx->priv;
 int err;
 
-err = overlay_vaapi_init_framesync(avctx);
-if (err < 0)
-return err;
-
+outlink->time_base = avctx->inputs[0]->time_base;
 vpp_ctx->output_width  = avctx->inputs[0]->w;
 vpp_ctx->output_height = avctx->inputs[0]->h;
 
@@ -313,6 +288,10 @@ static int overlay_vaapi_config_output(AVFilterLink 
*outlink)
 if (err < 0)
 return err;
 
+ctx->fs.on_event  = overlay_vaapi_blend;
+ctx->fs.opaque= ctx;
+ctx->fs.time_base = outlink->time_base;
+
 return ff_framesync_configure(>fs);
 }
 
-- 
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 v9 19/25] avfilter/subscale: Add filter for scaling and/or re-arranging graphical subtitles

2022-10-25 Thread softworkz
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 815e8e067f..8968851571 100755
--- a/configure
+++ b/configure
@@ -3755,6 +3755,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 6b05864706..5b058e8f3f 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -27954,6 +27954,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 targe

[FFmpeg-devel] [PATCH v9 25/25] avcodec/dvbsubdec: Fix conditions for fallback to default resolution

2022-10-25 Thread softworkz
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 c864ba3fb6..4df350574d 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -34,7 +34,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)
 
@@ -1450,8 +1450,12 @@ static int dvbsub_decode(AVCodecContext *avctx, 
AVSubtitle *sub,
 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");
 
@@ -1496,34 +1500,28 @@ static int dvbsub_decode(AVCodecContext *avctx, 
AVSubtitle *sub,
 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",
@@ -1536,13 +1534,24 @@ static int dvbsub_decode(AVCodecContext *avctx, 
AVSubtitle *sub,
 
 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 v9 23/25] avcodec/subtitles: Migrate subtitle encoders to frame-based API

2022-10-25 Thread softworkz
From: softworkz 

and provide a compatibility shim for the legacy api

Signed-off-by: softworkz 
---
 libavcodec/assenc.c | 189 ++--
 libavcodec/avcodec.h|   5 +-
 libavcodec/codec_internal.h |  12 ---
 libavcodec/dvbsubenc.c  |  96 ++
 libavcodec/dvdsubenc.c  | 103 
 libavcodec/encode.c |  61 +++-
 libavcodec/movtextenc.c | 114 --
 libavcodec/srtenc.c | 108 ++---
 libavcodec/tests/avcodec.c  |   5 +-
 libavcodec/ttmlenc.c| 101 ++-
 libavcodec/utils.c  |   1 -
 libavcodec/webvttenc.c  |  86 +++-
 libavcodec/xsubenc.c|  88 ++---
 13 files changed, 689 insertions(+), 280 deletions(-)

diff --git a/libavcodec/assenc.c b/libavcodec/assenc.c
index 9bbcdd9054..45fd5a217f 100644
--- a/libavcodec/assenc.c
+++ b/libavcodec/assenc.c
@@ -25,67 +25,192 @@
 
 #include "avcodec.h"
 #include "codec_internal.h"
+#include "encode.h"
 #include "libavutil/ass_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(_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(>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 + 

[FFmpeg-devel] [PATCH v9 22/25] avfilter/snull, strim: Add snull and strim filters

2022-10-25 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 configure|  2 +-
 libavfilter/Makefile |  2 ++
 libavfilter/allfilters.c |  2 ++
 libavfilter/sf_snull.c   | 61 
 libavfilter/trim.c   | 60 ++-
 5 files changed, 125 insertions(+), 2 deletions(-)
 create mode 100644 libavfilter/sf_snull.c

diff --git a/configure b/configure
index 3703aa216b..3d830be10f 100755
--- a/configure
+++ b/configure
@@ -3842,7 +3842,7 @@ avutil_extralibs="d3d11va_extralibs nanosleep_extralibs 
pthreads_extralibs vaapi
 # programs
 ffmpeg_deps="avcodec avfilter avformat threads"
 ffmpeg_select="aformat_filter anull_filter atrim_filter format_filter
-   hflip_filter null_filter
+   snull_filter strim_filter hflip_filter null_filter
transpose_filter trim_filter vflip_filter"
 ffmpeg_suggest="ole32 psapi shell32"
 ffplay_deps="avcodec avformat swscale swresample sdl2"
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index c6dfa517e8..4e5d33a43f 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -591,7 +591,9 @@ OBJS-$(CONFIG_NULLSINK_FILTER)   += 
vsink_nullsink.o
 # subtitle filters
 OBJS-$(CONFIG_CENSOR_FILTER) += sf_textmod.o
 OBJS-$(CONFIG_SHOW_SPEAKER_FILTER)   += sf_textmod.o
+OBJS-$(CONFIG_SNULL_FILTER)  += sf_snull.o
 OBJS-$(CONFIG_SPLITCC_FILTER)+= sf_splitcc.o
+OBJS-$(CONFIG_STRIM_FILTER)  += trim.o
 OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
 OBJS-$(CONFIG_SUBFEED_FILTER)+= sf_subfeed.o
 OBJS-$(CONFIG_SUBSCALE_FILTER)   += sf_subscale.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 8779141aad..9c84347659 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -579,7 +579,9 @@ extern const AVFilter ff_avsrc_movie;
 extern const AVFilter ff_sf_censor;
 extern const AVFilter ff_sf_graphicsub2text;
 extern const AVFilter ff_sf_showspeaker;
+extern const AVFilter ff_sf_snull;
 extern const AVFilter ff_sf_splitcc;
+extern const AVFilter ff_sf_strim;
 extern const AVFilter ff_sf_stripstyles;
 extern const AVFilter ff_sf_subfeed;
 extern const AVFilter ff_sf_subscale;
diff --git a/libavfilter/sf_snull.c b/libavfilter/sf_snull.c
new file mode 100644
index 00..815436cfff
--- /dev/null
+++ b/libavfilter/sf_snull.c
@@ -0,0 +1,61 @@
+/*
+ * 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
+ * null subtitle filter
+ */
+
+#include "avfilter.h"
+#include "internal.h"
+#include "libavutil/internal.h"
+
+static int sconfig_output(AVFilterLink *outlink)
+{
+AVFilterContext *ctx = outlink->src;
+AVFilterLink *inlink = ctx->inputs[0];
+
+outlink->format = inlink->format;
+
+return 0;
+}
+
+static const AVFilterPad avfilter_sf_snull_inputs[] = {
+{
+.name = "default",
+.type = AVMEDIA_TYPE_SUBTITLE,
+},
+};
+
+static const AVFilterPad avfilter_sf_snull_outputs[] = {
+{
+.name = "default",
+.type = AVMEDIA_TYPE_SUBTITLE,
+.config_props = sconfig_output,
+},
+};
+
+const AVFilter ff_sf_snull = {
+.name  = "snull",
+.description   = NULL_IF_CONFIG_SMALL("Pass the source unchanged to the 
output."),
+.flags = AVFILTER_FLAG_METADATA_ONLY,
+FILTER_INPUTS(avfilter_sf_snull_inputs),
+FILTER_OUTPUTS(avfilter_sf_snull_outputs),
+};
diff --git a/libavfilter/trim.c b/libavfilter/trim.c
index ee6e821cd2..a25366497b 100644
--- a/libavfilter/trim.c
+++ b/libavfilter/trim.c
@@ -83,7 +83,7 @@ static int config_input(AVFilterLink *inlink)
 {
 AVFilterContext *ctx = inlink->dst;
 TrimContext   *s = ctx->priv;
-AVRational tb = (inlink->type == AVMEDIA_TYPE_VIDEO) ?
+AVRational tb = (inlink->type != AVMEDIA_TYPE_AUDIO) ?
  inlink->time_base : (AVRational){ 1, inlink->sample_rate 
};
 
 if (s->start_time != INT64_MAX) {
@@ -369,3 +369,61 @@ const AVFilter ff_af_atrim = {

[FFmpeg-devel] [PATCH v9 21/25] avfilter/text2graphicsub: Added text2graphicsub subtitle filter

2022-10-25 Thread softworkz
From: softworkz 

Added a text2graphicsub subtitle filter which converts text-based
subtitle tracks to bitmap-based subtitle tracks. The filter uses libass
to render the subtitles.
It takes as parameters an output height and width, as well as a number
of colors in the output palette as well as sources of fonts. All its
arguments are optional.

Reviewed-by: softworkz 
Signed-off-by: softworkz 
Signed-off-by: tcoza 
---
 configure|   1 +
 doc/filters.texi |  51 +++
 libavfilter/Makefile |   1 +
 libavfilter/allfilters.c |   1 +
 libavfilter/sf_text2graphicsub.c | 634 +++
 5 files changed, 688 insertions(+)
 create mode 100644 libavfilter/sf_text2graphicsub.c

diff --git a/configure b/configure
index 8968851571..3703aa216b 100755
--- a/configure
+++ b/configure
@@ -3759,6 +3759,7 @@ subscale_filter_deps="swscale avcodec"
 subtitles_filter_deps="avformat avcodec libass"
 super2xsai_filter_deps="gpl"
 pixfmts_super2xsai_test_deps="super2xsai_filter"
+text2graphicsub_filter_deps="avformat avcodec libass"
 textsub2video_filter_deps="avcodec libass"
 tinterlace_filter_deps="gpl"
 tinterlace_merge_test_deps="tinterlace_filter"
diff --git a/doc/filters.texi b/doc/filters.texi
index 5b058e8f3f..ebd398386b 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -28118,6 +28118,57 @@ ffmpeg -y -y -loglevel verbose -i 
"https://streams.videolan.org/samples/sub/larg
 @end example
 @end itemize
 
+@section text2graphicsub
+
+Converts a text-based subtitle track to a bitmap-based subtitle track.
+
+The text2graphicsub filter uses libass to render all the subtitle
+frames in a text-based subtitle track (such as srt or ass) to allow
+its encoding with a bitmap-based subtitle encoder (such as dvd_subtitle).
+
+Inputs:
+- 0: Subtitles [text]
+
+Outputs:
+- 0: Subtitles [bitmap]
+
+It accepts the following parameters:
+
+@table @option
+
+@item s, size
+Set the size of the output. Default from input track.
+
+@item n, num_colors
+Set the number of palette colors for output images,
+Range [2,256]. Default 16.
+
+@item f, filename
+Set the media container from which to extract fonts required
+for rendering the subtitles, usually the same as the input
+track's media container. Can be omitted.
+
+@item fd, fontsdir
+Set the directory from which to load fonts required for
+rendering the subtitles. Can be used with 'fonts'. Can be omitted.
+
+@item ss, stripstyles
+Remove certain styles from an ass track which do not render well.
+Stripped styles include blurs, fades, and other animations.
+Default yes.
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Convert a video's text-based subtitle track to a dvd_subtitle subtitle track.
+@example
+ffmpeg -i video.mkv -map 0:v -map 0:a -filter_complex 
[0:s]text2graphicsub=f=video.mkv[dvd_sub] -map [dvd_sub] -c copy -c:s 
dvd_subtitle output.mkv
+@end example
+@end itemize
+
 @c man end SUBTITLE FILTERS
 
 @chapter Multimedia Filters
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 4a8badeddf..c6dfa517e8 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -595,6 +595,7 @@ OBJS-$(CONFIG_SPLITCC_FILTER)+= sf_splitcc.o
 OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
 OBJS-$(CONFIG_SUBFEED_FILTER)+= sf_subfeed.o
 OBJS-$(CONFIG_SUBSCALE_FILTER)   += sf_subscale.o
+OBJS-$(CONFIG_TEXT2GRAPHICSUB_FILTER)+= sf_text2graphicsub.o
 OBJS-$(CONFIG_TEXTMOD_FILTER)+= sf_textmod.o
 
 # multimedia filters
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index fe5f815731..8779141aad 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -583,6 +583,7 @@ extern const AVFilter ff_sf_splitcc;
 extern const AVFilter ff_sf_stripstyles;
 extern const AVFilter ff_sf_subfeed;
 extern const AVFilter ff_sf_subscale;
+extern const AVFilter ff_sf_text2graphicsub;
 extern const AVFilter ff_sf_textmod;
 
 /* those filters are part of public or internal API,
diff --git a/libavfilter/sf_text2graphicsub.c b/libavfilter/sf_text2graphicsub.c
new file mode 100644
index 00..1fd7a76c53
--- /dev/null
+++ b/libavfilter/sf_text2graphicsub.c
@@ -0,0 +1,634 @@
+/*
+ * Copyright (c) 2021 tcoza
+ *
+ * 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

[FFmpeg-devel] [PATCH v9 20/25] avfilter/subfeed: add subtitle feed filter

2022-10-25 Thread softworkz
From: softworkz 

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

diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 9dbac707d1..4a8badeddf 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -593,6 +593,7 @@ OBJS-$(CONFIG_CENSOR_FILTER) += sf_textmod.o
 OBJS-$(CONFIG_SHOW_SPEAKER_FILTER)   += sf_textmod.o
 OBJS-$(CONFIG_SPLITCC_FILTER)+= sf_splitcc.o
 OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
+OBJS-$(CONFIG_SUBFEED_FILTER)+= sf_subfeed.o
 OBJS-$(CONFIG_SUBSCALE_FILTER)   += sf_subscale.o
 OBJS-$(CONFIG_TEXTMOD_FILTER)+= sf_textmod.o
 
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 9c64f3f585..fe5f815731 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -581,6 +581,7 @@ extern const AVFilter ff_sf_graphicsub2text;
 extern const AVFilter ff_sf_showspeaker;
 extern const AVFilter ff_sf_splitcc;
 extern const AVFilter ff_sf_stripstyles;
+extern const AVFilter ff_sf_subfeed;
 extern const AVFilter ff_sf_subscale;
 extern const AVFilter ff_sf_textmod;
 
diff --git a/libavfilter/sf_subfeed.c b/libavfilter/sf_subfeed.c
new file mode 100644
index 00..3227861ac0
--- /dev/null
+++ b/libavfilter/sf_subfeed.c
@@ -0,0 +1,412 @@
+/*
+ * 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(>fifo, NULL);
+
+return 0;
+}
+
+static void uninit(AVFilterContext *ctx)
+{
+SubFeedContext *s = ctx->priv;
+ff_framequeue_free(>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, >outcfg.formats)) < 0)
+return ret;
+
+if ((ret = ff_formats_ref(formats, >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 = in

[FFmpeg-devel] [PATCH v9 18/25] avfilter/graphicsub2text: Add new graphicsub2text filter (OCR)

2022-10-25 Thread softworkz
From: softworkz 

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

diff --git a/configure b/configure
index a992a4795f..815e8e067f 100755
--- a/configure
+++ b/configure
@@ -3687,6 +3687,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 d1954b280f..6b05864706 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -27548,6 +27548,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 66c2210a46..03dd8ed5ef 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -314,6 +314,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_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
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 529ccbf760..a1137e6c25 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -577,6 +577,7 @@ extern const AVFilter ff_avsrc_movie;
 
 /* subtitle filters */
 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..47c7030939
--- /dev/null
+++ b/libavfilter/sf_graphicsub2text.c
@@ -0,0 +1,1137 @@
+/*
+ * 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.
+ 

[FFmpeg-devel] [PATCH v9 08/25] fftools/play, probe: Adjust for subtitle changes

2022-10-25 Thread softworkz
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 bcc00afe31..4ec186a0b3 100644
--- a/fftools/ffplay.c
+++ b/fftools/ffplay.c
@@ -153,7 +153,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 */
@@ -574,7 +573,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 (;;) {
@@ -608,6 +607,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;
@@ -640,25 +642,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, _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);
 }
 }
 }
@@ -671,7 +659,6 @@ static void decoder_destroy(Decoder *d) {
 static void frame_queue_unref_item(Frame *vp)
 {
 av_frame_unref(vp->frame);
-avsubtitle_free(>sub);
 }
 
 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, 
int keep_last)
@@ -969,7 +956,7 @@ static void video_image_display(VideoState *is)
 if (frame_queue_nb_remaining(>subpq) > 0) {
 sp = frame_queue_peek(>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];
@@ -981,25 +968,27 @@ static void video_image_display(VideoState *is)
 if (realloc_texture(>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

[FFmpeg-devel] [PATCH v9 16/25] avfilter/stripstyles: Add stripstyles filter

2022-10-25 Thread softworkz
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 | 237 +++
 4 files changed, 276 insertions(+)
 create mode 100644 libavfilter/sf_stripstyles.c

diff --git a/doc/filters.texi b/doc/filters.texi
index 1f7989e92f..383e020c8d 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -27432,6 +27432,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 5d82b3e8c4..01b7440cce 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -590,6 +590,7 @@ OBJS-$(CONFIG_NULLSINK_FILTER)   += 
vsink_nullsink.o
 # subtitle filters
 OBJS-$(CONFIG_CENSOR_FILTER) += sf_textmod.o
 OBJS-$(CONFIG_SHOW_SPEAKER_FILTER)   += sf_textmod.o
+OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
 OBJS-$(CONFIG_TEXTMOD_FILTER)+= sf_textmod.o
 
 # multimedia filters
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index d7f24ab7db..33bfae7358 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -578,6 +578,7 @@ extern const AVFilter ff_avsrc_movie;
 /* subtitle filters */
 extern const AVFilter ff_sf_censor;
 extern const AVFilter ff_sf_showspeaker;
+extern const AVFilter ff_sf_stripstyles;
 extern const AVFilter ff_sf_textmod;
 
 /* those filters are part of public or internal API,
diff --git a/libavfilter/sf_stripstyles.c b/libavfilter/sf_stripstyles.c
new file mode 100644
index 00..78dc6f3ef4
--- /dev/null
+++ b/libavfilter/sf_stripstyles.c
@@ -0,0 +1,237 @@
+/*
+ * 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_internal.h"
+#include "libavutil/ass_split_internal.h"
+#include "libavutil/bprint.h"
+
+typedef struct StripStylesContext {
+const AVClass *class;
+enum AVSubtitleType format;
+int remove_animated;
+enum ASSSplitComponents keep_flags;
+int select_layer;
+} StripStylesContext;
+
+typedef struct DialogContext {
+StripStylesContext* ss_ctx;
+AVBPrint buffer;
+int drawing_scale;
+int is_animated;
+int plain_text_length;
+} 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))
+s->plain_text_length += len;
+av_bprint_append_data(>buffer, text, len);
+}
+
+static void dialog_new_line_cb(void *priv, int forced)
+{

[FFmpeg-devel] [PATCH v9 17/25] avfilter/splitcc: Add splitcc filter for closed caption handling

2022-10-25 Thread softworkz
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 61a7bd1438..a992a4795f 100755
--- a/configure
+++ b/configure
@@ -3753,6 +3753,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 383e020c8d..d1954b280f 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -27782,6 +27782,69 @@ ffmpeg -i INPUT -filter_complex 
"showspeaker=format=colon:style='@{\\c&\
 @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 01b7440cce..66c2210a46 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -590,6 +590,7 @@ OBJS-$(CONFIG_NULLSINK_FILTER)   += 
vsink_nullsink.o
 # subtitle filters
 OBJS-$(CONFIG_CENSOR_FILTER) += sf_textmod.o
 OBJS-$(CONFIG_SHOW_SPEAKER_FILTER)   += sf_textmod.o
+OBJS-$(CONFIG_SPLITCC_FILTER)+= sf_splitcc.o
 OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
 OBJS-$(CONFIG_TEXTMOD_FILTER)+= sf_textmod.o
 
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 33bfae7358..529ccbf760 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -578,6 +578,7 @@ extern const AVFilter ff_avsrc_movie;
 /* subtitle filters */
 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;
 
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,
+ * b

[FFmpeg-devel] [PATCH v9 15/25] avfilter/textmod: Add textmod, censor and show_speaker filters

2022-10-25 Thread softworkz
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 |   5 +
 libavfilter/sf_textmod.c | 710 +++
 4 files changed, 926 insertions(+)
 create mode 100644 libavfilter/sf_textmod.c

diff --git a/doc/filters.texi b/doc/filters.texi
index fa6fd57cdc..1f7989e92f 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -27372,6 +27372,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
+R

[FFmpeg-devel] [PATCH v9 14/25] avfilter/overlaytextsubs: Add overlaytextsubs and textsubs2video filters

2022-10-25 Thread softworkz
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 |   2 +
 libavfilter/vf_overlaytextsubs.c | 680 +++
 5 files changed, 799 insertions(+)
 create mode 100644 libavfilter/vf_overlaytextsubs.c

diff --git a/configure b/configure
index b3f242469b..61a7bd1438 100755
--- a/configure
+++ b/configure
@@ -3716,6 +3716,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"
@@ -3755,6 +3756,7 @@ stereo3d_filter_deps="gpl"
 subtitles_filter_deps="avformat avcodec libass"
 super2xsai_filter_deps="gpl"
 pixfmts_super2xsai_test_deps="super2xsai_filter"
+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 70a371ee0e..fa6fd57cdc 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -27480,6 +27480,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 
overlaytextsubs 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 ",".

[FFmpeg-devel] [PATCH v9 13/25] avfilter/overlaygraphicsubs: Add overlaygraphicsubs and graphicsub2video filters

2022-10-25 Thread softworkz
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 bcd19cf931..70a371ee0e 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -27364,6 +27364,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 
'overlaygraphicsubs' 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 overlaygraphicsubs)
+@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 6db90028e0..0dae913b16 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -314,6 +314,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_GRAPHMONITO

[FFmpeg-devel] [PATCH v9 12/25] avfilter/sbuffer: Add sbuffersrc and sbuffersink filters

2022-10-25 Thread softworkz
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 431fa5bf7a..b3f242469b 100755
--- a/configure
+++ b/configure
@@ -7954,7 +7954,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 "_%s,\n" $c >> $TMPH
 done
 fi
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 119de40b25..173d85b982 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -577,8 +577,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 e269cf72d1..204e9bad6c 100644
--- a/libavfilter/buffersink.c
+++ b/libavfilter/buffersink.c
@@ -30,6 +30,8 @@
 #include "libavutil/internal.h"
 #include "libavutil/opt.h"
 
+#include "libavcodec/avcodec.h"
+
 #define FF_INTERNAL_FIELDS 1
 #include "framequeue.h"
 
@@ -61,6 +63,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;
 
@@ -372,6 +378,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_format(, 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[] = {
@@ -395,9 +423,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[] = {
 {
@@ -436,3 +471,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= _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 01e7c747d8..42c164e670 100644
--- a/libavfilter/buffersink.h
+++ b/libavfilter/buffersink.h
@@ -128,6 +128,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;
+} AVSBufferSinkP

[FFmpeg-devel] [PATCH v9 06/25] avcodec, avutil: Move ass helper functions to avutil as avpriv_ and extend ass dialog parsing

2022-10-25 Thread softworkz
From: softworkz 

Also add

- hard_space callback (for upcoming fix)
- extensible callback (for future extension)
- new API which allows tag filtering

Signed-off-by: softworkz 
---
 libavcodec/Makefile   |  56 +++---
 libavcodec/ass.h  | 151 +--
 libavcodec/ass_split.h| 191 ---
 libavcodec/assdec.c   |   2 +-
 libavcodec/assenc.c   |   2 +-
 libavcodec/ccaption_dec.c |  20 +-
 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   | 115 
 libavutil/ass_internal.h  | 135 ++
 {libavcodec => libavutil}/ass_split.c | 179 +++---
 libavutil/ass_split_internal.h| 254 ++
 27 files changed, 726 insertions(+), 492 deletions(-)
 delete mode 100644 libavcodec/ass_split.h
 rename {libavcodec => libavutil}/ass.c (59%)
 create mode 100644 libavutil/ass_internal.h
 rename {libavcodec => libavutil}/ass_split.c (71%)
 create mode 100644 libavutil/ass_split_internal.h

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 90c7f113a3..58544b40ba 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -224,10 +224,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
@@ -269,7 +269,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
@@ -449,7 +449,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 \
@@ -472,7 +472,7 @@ OBJS-$(CONFIG_MDEC_DECODER)+= mdec.o mpeg12.o 
mpeg12data.o
 OBJS-$(CONFIG_MEDIA100_DECODER)+= media100.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_MISC4_DECODER)   += misc4.o
 OBJS-$(CONFIG_MJPEG_DECODER)   += mjpegdec.o mjpegdec_common.o
@@ -488,8 +488,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_ENCODER) += movtextenc.o ass_s

[FFmpeg-devel] [PATCH v9 11/25] avfilter/avfilter: Fix hardcoded input index

2022-10-25 Thread softworkz
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 b40a2fc7cd..6cd83ae34a 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -461,7 +461,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;
 
@@ -470,8 +470,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));
@@ -1171,6 +1171,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 (>dst->input_pads[i] == in->dstpad) {
+input_index = i;
+break;
+}
+}
 
 av_assert0(!in->status_out);
 if (!filter->nb_outputs) {
@@ -1180,7 +1188,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;
 }
@@ -1217,7 +1225,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 v9 07/25] avcodec/subtitles: Replace deprecated enum values

2022-10-25 Thread softworkz
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 2571118ee9..a274d7e92e 100644
--- a/libavcodec/assdec.c
+++ b/libavcodec/assdec.c
@@ -53,7 +53,7 @@ static int ass_decode_frame(AVCodecContext *avctx, AVSubtitle 
*sub,
 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 bcc607d1d7..c864ba3fb6 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -796,7 +796,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 a5da0d7b08..bf97b916c9 100644
--- a/libavcodec/dvdsubdec.c
+++ b/libavcodec/dvdsubdec.c
@@ -405,7 +405,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 0874aaa02d..624e21c000 100644
--- a/libavcodec/dvdsubenc.c
+++ b/libavcodec/dvdsubenc.c
@@ -269,7 +269,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 5f76f12615..65ba3ad261 100644
--- a/libavcodec/pgssubdec.c
+++ b/libavcodec/pgssubdec.c
@@ -534,7 +534,7 @@ static int display_end_segment(AVCodecContext *avctx, 
AVSubtitle *sub,
 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, >objects);
diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c
index f86b7c58e7..1b167e1d0a 100644
--- a/libavcodec/xsubdec.c
+++ b/libavcodec/xsubdec.c
@@ -107,7 +107,7 @@ static int decode_frame(AVCodecContext *avctx, AVSubtitle 
*sub,
 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 v9 10/25] avfilter/avfilter: Handle subtitle frames

2022-10-25 Thread softworkz
From: softworkz 

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

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index e49d76c14a..b40a2fc7cd 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -54,7 +54,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,
@@ -62,8 +63,8 @@ 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:
 AVBPrint bprint;
 
 av_bprint_init(, 1, AV_BPRINT_SIZE_UNLIMITED);
@@ -73,6 +74,7 @@ static void tlog_ref(void *ctx, AVFrame *ref, int end)
 ref->nb_samples,
 ref->sample_rate);
 av_bprint_finalize(, NULL);
+break;
 }
 
 ff_tlog(ctx, "]%s", end ? "\n" : "");
@@ -356,6 +358,14 @@ int avfilter_config_links(AVFilterContext *filter)
 
 if (!link->time_base.num && !link->time_base.den)
 link->time_base = (AVRational) {1, link->sample_rate};
+
+break;
+
+case AVMEDIA_TYPE_SUBTITLE:
+if (!link->time_base.num && !link->time_base.den)
+link->time_base = inlink ? inlink->time_base : 
AV_TIME_BASE_Q;
+
+break;
 }
 
 if (link->src->nb_inputs && link->src->inputs[0]->hw_frames_ctx &&
@@ -1023,6 +1033,10 @@ int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
 av_assert1(frame->width   == link->w);
 av_assert1(frame->height   == link->h);
 }
+} else if (link->type == AVMEDIA_TYPE_SUBTITLE) {
+if (frame->format != link->format) {
+av_log(link->dst, AV_LOG_WARNING, "Subtitle format change from %d 
to %d\n", link->format, frame->format);
+}
 } else {
 if (frame->format != link->format) {
 av_log(link->dst, AV_LOG_ERROR, "Format change is not 
supported\n");
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 6d68ebece4..82f6b21520 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_major.h"
@@ -356,6 +357,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.
  */
@@ -364,6 +371,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 53f468494d..f7547467f0 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -309,6 +309,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");
 }
@@ -439,6 +441,9 @@ static int query_formats(AVFilterGraph *graph, void 
*log_ctx)
 if (!link)
 continue;
 
+ 

[FFmpeg-devel] [PATCH v9 09/25] avfilter/subtitles: Add subtitles.c for subtitle frame allocation

2022-10-25 Thread softworkz
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 ff2a06c262..6db90028e0 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -21,6 +21,7 @@ OBJS = allfilters.o   
  \
framequeue.o \
graphdump.o  \
graphparser.o\
+   subtitles.o  \
version.o\
video.o  \
 
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index cc5505e65b..e49d76c14a 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"
 
 static void tlog_ref(void *ctx, AVFrame *ref, int end)
 {
@@ -1462,6 +1463,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 aaf2c6c584..1a0752e4ee 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -89,6 +89,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();
+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 000000..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 

[FFmpeg-devel] [PATCH v9 05/25] avfilter/subtitles: Update vf_subtitles to use new decoding api

2022-10-25 Thread softworkz
From: softworkz 

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

diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c
index 82e140e986..0ae156ad07 100644
--- a/libavfilter/vf_subtitles.c
+++ b/libavfilter/vf_subtitles.c
@@ -36,14 +36,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;
@@ -304,8 +302,42 @@ 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 enum AVSubtitleType 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;
+}
+
 static av_cold int init_subtitles(AVFilterContext *ctx)
 {
 int j, ret, sid;
@@ -318,6 +350,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);
@@ -398,13 +431,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 = 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(_opts, "sub_charenc", ass->charenc, 0);
 
@@ -460,27 +497,31 @@ static av_cold int init_subtitles(AVFilterContext *ctx)
   dec_ctx->subtitle_header_size);
 while (av_read_frame(fmt, ) >= 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, , _subtitle, );
+ret = decode(dec_ctx, sub, _subtitle, );
 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();
-avsubtitle_free();
+av_frame_free();
 }
 
 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 v9 04/25] avcodec/libzvbi: set subtitle type

2022-10-25 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/libzvbi-teletextdec.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavcodec/libzvbi-teletextdec.c b/libavcodec/libzvbi-teletextdec.c
index 45e30eb01c..486aa1724e 100644
--- a/libavcodec/libzvbi-teletextdec.c
+++ b/libavcodec/libzvbi-teletextdec.c
@@ -751,10 +751,13 @@ static int teletext_init_decoder(AVCodecContext *avctx)
 
 switch (ctx->format_id) {
 case 0:
+avctx->subtitle_type = AV_SUBTITLE_FMT_BITMAP;
 return 0;
 case 1:
+avctx->subtitle_type = AV_SUBTITLE_FMT_ASS;
 return ff_ass_subtitle_header_default(avctx);
 case 2:
+avctx->subtitle_type = AV_SUBTITLE_FMT_ASS;
 return my_ass_subtitle_header(avctx);
 }
 return AVERROR_BUG;
-- 
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 v9 03/25] avcodec/subtitles: Introduce new frame-based subtitle decoding API

2022-10-25 Thread softworkz
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.c  |   8 ++
 libavcodec/avcodec.h  |  10 ++-
 libavcodec/decode.c   |  60 --
 libavcodec/internal.h |  18 +
 libavcodec/utils.c| 184 ++
 5 files changed, 271 insertions(+), 9 deletions(-)

diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
index a85d3c2309..3518dd2185 100644
--- a/libavcodec/avcodec.c
+++ b/libavcodec/avcodec.c
@@ -350,6 +350,14 @@ FF_ENABLE_DEPRECATION_WARNINGS
 goto free_and_end;
 }
 
+// Set the subtitle type from the codec descriptor in case the decoder 
hasn't done itself
+if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE && avctx->subtitle_type 
== AV_SUBTITLE_FMT_UNKNOWN) {
+if(avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB)
+avctx->subtitle_type = AV_SUBTITLE_FMT_BITMAP;
+if(avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB)
+ avctx->subtitle_type = AV_SUBTITLE_FMT_ASS;
+}
+
 #if FF_API_AVCTX_TIMEBASE
 if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
 avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, 
(AVRational){avctx->ticks_per_frame, 1}));
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index bf06b01e22..68b588861f 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1700,7 +1700,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())
@@ -2058,6 +2058,8 @@ typedef struct AVCodecContext {
  * The decoder can then override during decoding as needed.
  */
 AVChannelLayout ch_layout;
+
+enum AVSubtitleType subtitle_type;
 } AVCodecContext;
 
 /**
@@ -2434,7 +2436,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);
 
 /**
@@ -2533,7 +2538,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/decode.c b/libavcodec/decode.c
index 6be2d3d6ed..6a4702807a 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -634,6 +634,39 @@ FF_ENABLE_DEPRECATION_WARNINGS
 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, , _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, );
+
+frame->width = avctx->width;
+frame->height = avctx->height;
+frame->pkt_dts = avpkt->dts;
+}
+
+avsubtitle_free();
+
+return ret;
+}
+
 int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const 
AVPacket *avpkt)
 {
 AVCodecInternal *avci = avctx->internal;
@@ -648,6 +681,13 @@ int attribute_align_arg avcodec_send_packet(AVCodecContext 
*avctx, const AVPacke
 if (avpkt && !avpkt->size && avpkt->data)
   

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

2022-10-25 Thread softworkz
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  | 206 +
 libavutil/frame.h  |  85 ++-
 libavutil/subfmt.c |  45 ++
 libavutil/subfmt.h |  47 +++
 5 files changed, 363 insertions(+), 21 deletions(-)
 create mode 100644 libavutil/subfmt.c

diff --git a/libavutil/Makefile b/libavutil/Makefile
index 74380cf917..4ab4fcb01b 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -165,6 +165,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 de4ad1f94d..230673e4e1 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"
 
 #if FF_API_OLD_CHANNEL_LAYOUT
@@ -52,6 +53,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));
@@ -77,7 +81,12 @@ FF_ENABLE_DEPRECATION_WARNINGS
 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)
@@ -256,6 +265,23 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
 }
 
+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->format < 0)
@@ -263,23 +289,41 @@ int av_frame_get_buffer(AVFrame *frame, int align)
 
 FF_DISABLE_DEPRECATION_WARNINGS
 if (frame->width > 0 && frame->height > 0)
-return get_video_buffer(frame, align);
+frame->type = AVMEDIA_TYPE_VIDEO;
 else if (frame->nb_samples > 0 &&
  (av_channel_layout_check(>ch_layout)
 #if FF_API_OLD_CHANNEL_LAYOUT
   || frame->channel_layout || frame->channels > 0
 #endif
  ))
-return get_audio_buffer(frame, align);
+frame->type = AVMEDIA_TYPE_AUDIO;
 FF_ENABLE_DEPRECATION_WARNINGS
 
-return AVERROR(EINVAL);
+return av_frame_get_buffer2(frame, align);
+}
+
+int av_frame_get_buffer2(AVFrame *frame, int align)
+{
+if (frame->format < 0)
+return AVERROR(EINVAL);
+
+switch (frame->type) {
+case AVMEDIA_TYPE_VIDEO:
+return get_video_buffer(frame, align);
+case AVMEDIA_TYPE_AUDIO:
+return get_audio_buffer(frame, align);
+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_

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

2022-10-25 Thread softworkz
From: softworkz 

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

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 3edd8e2636..bf06b01e22 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"
@@ -2257,24 +2258,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 3d9c07aea8..74380cf917 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -77,6 +77,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 cb0c928bd0..009c628e35 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,8 +79,8 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  57
-#define LIBAVUTIL_VERSION_MINOR  39
-#define LIBAVUTIL_VERSION_MICRO 101
+#define LIBAVUTIL_VERSION_MINOR  40
+#define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
LIBAVUTIL_VERSION_MINOR, \
@@ -115,6 +115,7 @@
 #define FF_API_OLD_CHANNEL_LAYOUT   (LIBAVUTIL_VE

[FFmpeg-devel] [PATCH v6 3/3] avcodec/qsvdec: Implement SEI parsing for QSV decoders

2022-10-24 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/Makefile |   2 +-
 libavcodec/qsvdec.c | 321 
 2 files changed, 322 insertions(+), 1 deletion(-)

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 90c7f113a3..cbddbb0ace 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -146,7 +146,7 @@ OBJS-$(CONFIG_MSS34DSP)+= mss34dsp.o
 OBJS-$(CONFIG_PIXBLOCKDSP) += pixblockdsp.o
 OBJS-$(CONFIG_QPELDSP) += qpeldsp.o
 OBJS-$(CONFIG_QSV) += qsv.o
-OBJS-$(CONFIG_QSVDEC)  += qsvdec.o
+OBJS-$(CONFIG_QSVDEC)  += qsvdec.o h264_sei.o hevc_sei.o
 OBJS-$(CONFIG_QSVENC)  += qsvenc.o
 OBJS-$(CONFIG_RANGECODER)  += rangecoder.o
 OBJS-$(CONFIG_RDFT)+= rdft.o
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 73405b5747..467a248224 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -41,6 +41,7 @@
 #include "libavutil/time.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/film_grain_params.h"
+#include 
 
 #include "avcodec.h"
 #include "codec_internal.h"
@@ -49,6 +50,9 @@
 #include "hwconfig.h"
 #include "qsv.h"
 #include "qsv_internal.h"
+#include "h264_sei.h"
+#include "hevc_ps.h"
+#include "hevc_sei.h"
 
 #if QSV_ONEVPL
 #include 
@@ -66,6 +70,8 @@ static const AVRational mfx_tb = { 1, 9 };
 AV_NOPTS_VALUE : pts_tb.num ? \
 av_rescale_q(mfx_pts, mfx_tb, pts_tb) : mfx_pts)
 
+#define PAYLOAD_BUFFER_SIZE 65535
+
 typedef struct QSVAsyncFrame {
 mfxSyncPoint *sync;
 QSVFrame *frame;
@@ -107,6 +113,9 @@ typedef struct QSVContext {
 
 mfxExtBuffer **ext_buffers;
 int nb_ext_buffers;
+
+mfxU8 payload_buffer[PAYLOAD_BUFFER_SIZE];
+AVBufferRef *a53_buf_ref;
 } QSVContext;
 
 static const AVCodecHWConfigInternal *const qsv_hw_configs[] = {
@@ -628,6 +637,299 @@ static int qsv_export_film_grain(AVCodecContext *avctx, 
mfxExtAV1FilmGrainParam
 }
 #endif
 
+static int find_start_offset(mfxU8 data[4])
+{
+if (data[0] == 0 && data[1] == 0 && data[2] == 1)
+return 3;
+
+if (data[0] == 0 && data[1] == 0 && data[2] == 0 && data[3] == 1)
+return 4;
+
+return 0;
+}
+
+static int parse_sei_h264(AVCodecContext* avctx, QSVContext* q, AVFrame* out)
+{
+H264SEIContext sei = { 0 };
+GetBitContext gb = { 0 };
+mfxPayload payload = { 0, .Data = >payload_buffer[0], .BufSize = 
sizeof(q->payload_buffer) - AV_INPUT_BUFFER_PADDING_SIZE };
+mfxU64 ts;
+int ret;
+
+while (1) {
+int start;
+memset(payload.Data, 0, payload.BufSize);
+
+ret = MFXVideoDECODE_GetPayload(q->session, , );
+if (ret == MFX_ERR_NOT_ENOUGH_BUFFER) {
+av_log(avctx, AV_LOG_WARNING, "Warning: Insufficient buffer on 
GetPayload(). Size: %"PRIu64" Needed: %d\n", sizeof(q->payload_buffer), 
payload.BufSize);
+return 0;
+}
+if (ret != MFX_ERR_NONE)
+return ret;
+
+if (payload.NumBit == 0 || payload.NumBit >= payload.BufSize * 8)
+break;
+
+start = find_start_offset(payload.Data);
+
+switch (payload.Type) {
+case SEI_TYPE_BUFFERING_PERIOD:
+case SEI_TYPE_PIC_TIMING:
+continue;
+}
+
+if (init_get_bits(, [start], payload.NumBit - start * 
8) < 0)
+av_log(avctx, AV_LOG_ERROR, "Error initializing bitstream reader 
SEI type: %d  Numbits %d error: %d\n", payload.Type, payload.NumBit, ret);
+else {
+ret = ff_h264_sei_decode(, , NULL, avctx);
+
+if (ret < 0)
+av_log(avctx, AV_LOG_WARNING, "Failed to parse SEI type: %d  
Numbits %d error: %d\n", payload.Type, payload.NumBit, ret);
+else
+av_log(avctx, AV_LOG_DEBUG, "mfxPayload Type: %d  Numbits 
%d\n", payload.Type, payload.NumBit);
+}
+}
+
+if (out)
+return ff_h264_set_sei_to_frame(avctx, , out, NULL, 0);
+
+return 0;
+}
+
+static int parse_sei_hevc(AVCodecContext* avctx, QSVContext* q, QSVFrame* out)
+{
+HEVCSEI sei = { 0 };
+HEVCParamSets ps = { 0 };
+GetBitContext gb = { 0 };
+mfxPayload payload = { 0, .Data = >payload_buffer[0], .BufSize = 
sizeof(q->payload_buffer) - AV_INPUT_BUFFER_PADDING_SIZE };
+mfxFrameSurface1 *surface = >surface;
+mfxU64 ts;
+int ret, has_logged = 0;
+
+while (1) {
+int start;
+memset(payload.Data, 0, payload.BufSize);
+
+ret = MFXVideoDECODE_GetPayload(q->session, , );
+if (ret == MFX_ERR_NOT_ENOUGH_BUFFER) {
+av_log(avctx, AV_LOG_WARNING, "Warning: Insufficient buffer on

[FFmpeg-devel] [PATCH v6 2/3] avcodec/h264dec: make h264_export_frame_props() accessible

2022-10-24 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/h264_sei.c   | 197 
 libavcodec/h264_sei.h   |   2 +
 libavcodec/h264_slice.c | 190 +-
 3 files changed, 200 insertions(+), 189 deletions(-)

diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c
index 034ddb8f1c..d3612fdbc0 100644
--- a/libavcodec/h264_sei.c
+++ b/libavcodec/h264_sei.c
@@ -38,6 +38,10 @@
 #include "h264_ps.h"
 #include "h264_sei.h"
 #include "sei.h"
+#include "libavutil/display.h"
+#include "libavutil/film_grain_params.h"
+#include "libavutil/stereo3d.h"
+#include "libavutil/timecode.h"
 
 #define AVERROR_PS_NOT_FOUND  FFERRTAG(0xF8,'?','P','S')
 
@@ -587,3 +591,196 @@ const char *ff_h264_sei_stereo_mode(const 
H264SEIFramePacking *h)
 return NULL;
 }
 }
+
+int ff_h264_set_sei_to_frame(AVCodecContext *avctx, H264SEIContext *sei, 
AVFrame *out, const SPS *sps, uint64_t seed)
+{
+if (sei->frame_packing.present &&
+sei->frame_packing.arrangement_type <= 6 &&
+sei->frame_packing.content_interpretation_type > 0 &&
+sei->frame_packing.content_interpretation_type < 3) {
+H264SEIFramePacking *fp = >frame_packing;
+AVStereo3D *stereo = av_stereo3d_create_side_data(out);
+if (stereo) {
+switch (fp->arrangement_type) {
+case H264_SEI_FPA_TYPE_CHECKERBOARD:
+stereo->type = AV_STEREO3D_CHECKERBOARD;
+break;
+case H264_SEI_FPA_TYPE_INTERLEAVE_COLUMN:
+stereo->type = AV_STEREO3D_COLUMNS;
+break;
+case H264_SEI_FPA_TYPE_INTERLEAVE_ROW:
+stereo->type = AV_STEREO3D_LINES;
+break;
+case H264_SEI_FPA_TYPE_SIDE_BY_SIDE:
+if (fp->quincunx_sampling_flag)
+stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
+else
+stereo->type = AV_STEREO3D_SIDEBYSIDE;
+break;
+case H264_SEI_FPA_TYPE_TOP_BOTTOM:
+stereo->type = AV_STEREO3D_TOPBOTTOM;
+break;
+case H264_SEI_FPA_TYPE_INTERLEAVE_TEMPORAL:
+stereo->type = AV_STEREO3D_FRAMESEQUENCE;
+break;
+case H264_SEI_FPA_TYPE_2D:
+stereo->type = AV_STEREO3D_2D;
+break;
+}
+
+if (fp->content_interpretation_type == 2)
+stereo->flags = AV_STEREO3D_FLAG_INVERT;
+
+if (fp->arrangement_type == H264_SEI_FPA_TYPE_INTERLEAVE_TEMPORAL) {
+if (fp->current_frame_is_frame0_flag)
+stereo->view = AV_STEREO3D_VIEW_LEFT;
+else
+stereo->view = AV_STEREO3D_VIEW_RIGHT;
+}
+}
+}
+
+if (sei->display_orientation.present &&
+(sei->display_orientation.anticlockwise_rotation ||
+ sei->display_orientation.hflip ||
+ sei->display_orientation.vflip)) {
+H264SEIDisplayOrientation *o = >display_orientation;
+double angle = o->anticlockwise_rotation * 360 / (double) (1 << 16);
+AVFrameSideData *rotation = av_frame_new_side_data(out,
+   
AV_FRAME_DATA_DISPLAYMATRIX,
+   sizeof(int32_t) * 
9);
+if (rotation) {
+/* av_display_rotation_set() expects the angle in the clockwise
+ * direction, hence the first minus.
+ * The below code applies the flips after the rotation, yet
+ * the H.2645 specs require flipping to be applied first.
+ * Because of R O(phi) = O(-phi) R (where R is flipping around
+ * an arbitatry axis and O(phi) is the proper rotation by phi)
+ * we can create display matrices as desired by negating
+ * the degree once for every flip applied. */
+angle = -angle * (1 - 2 * !!o->hflip) * (1 - 2 * !!o->vflip);
+av_display_rotation_set((int32_t *)rotation->data, angle);
+av_display_matrix_flip((int32_t *)rotation->data,
+   o->hflip, o->vflip);
+}
+}
+
+if (sei->afd.present) {
+AVFrameSideData *sd = av_frame_new_side_data(out, AV_FRAME_DATA_AFD,
+ sizeof(uint8_t));
+
+if (sd) {
+*sd->data = sei->afd.active_format_description;
+sei->afd.present = 0;
+}
+}
+
+if (sei->a53_caption.buf_ref) {
+H264SEIA53Caption *a53 = >a53_caption;
+
+AVFrameSideData *sd = av_frame_new_side_data_from_buf(out, 
AV_FRAME_DATA_A53_CC, a53->buf_ref);
+if (!sd)
+av_buffer_unref(>buf_ref);
+a53

[FFmpeg-devel] [PATCH v6 1/3] avcodec/hevcdec: factor out ff_hevc_set_set_to_frame

2022-10-24 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/hevc_sei.c | 252 ++
 libavcodec/hevc_sei.h |   3 +
 libavcodec/hevcdec.c  | 249 +
 3 files changed, 260 insertions(+), 244 deletions(-)

diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c
index 631373e06f..6fd066e44f 100644
--- a/libavcodec/hevc_sei.c
+++ b/libavcodec/hevc_sei.c
@@ -30,6 +30,12 @@
 #include "hevc_ps.h"
 #include "hevc_sei.h"
 
+#include "libavutil/display.h"
+#include "libavutil/film_grain_params.h"
+#include "libavutil/mastering_display_metadata.h"
+#include "libavutil/stereo3d.h"
+#include "libavutil/timecode.h"
+
 static int decode_nal_sei_decoded_picture_hash(HEVCSEIPictureHash *s,
GetByteContext *gb)
 {
@@ -578,3 +584,249 @@ void ff_hevc_reset_sei(HEVCSEI *s)
 av_buffer_unref(>dynamic_hdr_plus.info);
 av_buffer_unref(>dynamic_hdr_vivid.info);
 }
+
+int ff_hevc_set_sei_to_frame(AVCodecContext *logctx, HEVCSEI *sei, AVFrame 
*out, AVRational framerate, uint64_t seed, const VUI *vui, int bit_depth_luma, 
int bit_depth_chroma)
+{
+if (sei->frame_packing.present &&
+sei->frame_packing.arrangement_type >= 3 &&
+sei->frame_packing.arrangement_type <= 5 &&
+sei->frame_packing.content_interpretation_type > 0 &&
+sei->frame_packing.content_interpretation_type < 3) {
+AVStereo3D *stereo = av_stereo3d_create_side_data(out);
+if (!stereo)
+return AVERROR(ENOMEM);
+
+switch (sei->frame_packing.arrangement_type) {
+case 3:
+if (sei->frame_packing.quincunx_subsampling)
+stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
+else
+stereo->type = AV_STEREO3D_SIDEBYSIDE;
+break;
+case 4:
+stereo->type = AV_STEREO3D_TOPBOTTOM;
+break;
+case 5:
+stereo->type = AV_STEREO3D_FRAMESEQUENCE;
+break;
+}
+
+if (sei->frame_packing.content_interpretation_type == 2)
+stereo->flags = AV_STEREO3D_FLAG_INVERT;
+
+if (sei->frame_packing.arrangement_type == 5) {
+if (sei->frame_packing.current_frame_is_frame0_flag)
+stereo->view = AV_STEREO3D_VIEW_LEFT;
+else
+stereo->view = AV_STEREO3D_VIEW_RIGHT;
+}
+}
+
+if (sei->display_orientation.present &&
+(sei->display_orientation.anticlockwise_rotation ||
+ sei->display_orientation.hflip || sei->display_orientation.vflip)) {
+double angle = sei->display_orientation.anticlockwise_rotation * 360 / 
(double) (1 << 16);
+AVFrameSideData *rotation = av_frame_new_side_data(out,
+   
AV_FRAME_DATA_DISPLAYMATRIX,
+   sizeof(int32_t) * 
9);
+if (!rotation)
+return AVERROR(ENOMEM);
+
+/* av_display_rotation_set() expects the angle in the clockwise
+ * direction, hence the first minus.
+ * The below code applies the flips after the rotation, yet
+ * the H.2645 specs require flipping to be applied first.
+ * Because of R O(phi) = O(-phi) R (where R is flipping around
+ * an arbitatry axis and O(phi) is the proper rotation by phi)
+ * we can create display matrices as desired by negating
+ * the degree once for every flip applied. */
+angle = -angle * (1 - 2 * !!sei->display_orientation.hflip)
+   * (1 - 2 * !!sei->display_orientation.vflip);
+av_display_rotation_set((int32_t *)rotation->data, angle);
+av_display_matrix_flip((int32_t *)rotation->data,
+   sei->display_orientation.hflip,
+   sei->display_orientation.vflip);
+}
+
+if (sei->mastering_display.present) {
+// HEVC uses a g,b,r ordering, which we convert to a more natural r,g,b
+const int mapping[3] = {2, 0, 1};
+const int chroma_den = 5;
+const int luma_den = 1;
+int i;
+AVMasteringDisplayMetadata *metadata =
+av_mastering_display_metadata_create_side_data(out);
+if (!metadata)
+return AVERROR(ENOMEM);
+
+for (i = 0; i < 3; i++) {
+const int j = mapping[i];
+metadata->display_primaries[i][0].num = 
sei->mastering_display.display_primaries[j][0];
+metadata->display_primaries[i][0].den = chroma_den;
+metadata->display_primaries[i][1].num = 
sei->mastering_display.display_primaries[j][1];
+  

[FFmpeg-devel] [PATCH 2/2] avcodec/vpp_qsv: Copy side data from input to output frame

2022-10-24 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/qsvvpp.c |  6 ++
 libavfilter/vf_overlay_qsv.c | 19 +++
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
index 8428ee89ab..ae9766d12f 100644
--- a/libavfilter/qsvvpp.c
+++ b/libavfilter/qsvvpp.c
@@ -880,6 +880,12 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink 
*inlink, AVFrame *picr
 return AVERROR(EAGAIN);
 break;
 }
+
+av_frame_remove_all_side_data(out_frame->frame);
+ret = av_frame_copy_side_data(out_frame->frame, in_frame->frame, 0);
+if (ret < 0)
+return ret;
+
 out_frame->frame->pts = av_rescale_q(out_frame->surface.Data.TimeStamp,
  default_tb, outlink->time_base);
 
diff --git a/libavfilter/vf_overlay_qsv.c b/libavfilter/vf_overlay_qsv.c
index d947a1faa1..04fd284b92 100644
--- a/libavfilter/vf_overlay_qsv.c
+++ b/libavfilter/vf_overlay_qsv.c
@@ -231,13 +231,24 @@ static int process_frame(FFFrameSync *fs)
 {
 AVFilterContext  *ctx = fs->parent;
 QSVOverlayContext  *s = fs->opaque;
+AVFrame   *frame0 = NULL;
 AVFrame*frame = NULL;
-int   ret = 0, i;
+int   ret = 0;
 
-for (i = 0; i < ctx->nb_inputs; i++) {
+for (unsigned i = 0; i < ctx->nb_inputs; i++) {
 ret = ff_framesync_get_frame(fs, i, , 0);
-if (ret == 0)
-ret = ff_qsvvpp_filter_frame(s->qsv, ctx->inputs[i], frame);
+
+if (ret == 0) {
+if (i == 0)
+frame0 = frame;
+else {
+av_frame_remove_all_side_data(frame);
+ret = av_frame_copy_side_data(frame, frame0, 0);
+}
+
+ret = ret < 0 ? ret : ff_qsvvpp_filter_frame(s->qsv, 
ctx->inputs[i], frame);
+}
+
 if (ret < 0 && ret != AVERROR(EAGAIN))
 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 1/2] avutil/frame: Add av_frame_copy_side_data() and av_frame_remove_all_side_data()

2022-10-24 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
Signed-off-by: Anton Khirnov 
---
 doc/APIchanges  |  4 +++
 libavutil/frame.c   | 67 +++--
 libavutil/frame.h   | 32 ++
 libavutil/version.h |  4 +--
 4 files changed, 79 insertions(+), 28 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 5807bf8069..a65482ecc4 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,10 @@ libavutil: 2021-04-27
 
 API changes, most recent first:
 
+2022-05-26 - x - lavu 57.40.100 - frame.h
+  Add av_frame_remove_all_side_data(), av_frame_copy_side_data(),
+  AV_FRAME_TRANSFER_SD_COPY, and AV_FRAME_TRANSFER_SD_FILTER.
+
 2022-10-11 - xx - lavu 57.39.101 - pixfmt.h
   Add AV_PIX_FMT_RGBF32 and AV_PIX_FMT_RGBAF32.
 
diff --git a/libavutil/frame.c b/libavutil/frame.c
index de4ad1f94d..8eb0e1ec95 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -276,9 +276,45 @@ FF_ENABLE_DEPRECATION_WARNINGS
 return AVERROR(EINVAL);
 }
 
+void av_frame_remove_all_side_data(AVFrame *frame)
+{
+wipe_side_data(frame);
+}
+
+int av_frame_copy_side_data(AVFrame* dst, const AVFrame* src, int flags)
+{
+for (unsigned i = 0; i < src->nb_side_data; i++) {
+const AVFrameSideData *sd_src = src->side_data[i];
+AVFrameSideData *sd_dst;
+if ((flags & AV_FRAME_TRANSFER_SD_FILTER) &&
+sd_src->type == AV_FRAME_DATA_PANSCAN &&
+(src->width != dst->width || src->height != dst->height))
+continue;
+if (flags & AV_FRAME_TRANSFER_SD_COPY) {
+sd_dst = av_frame_new_side_data(dst, sd_src->type,
+sd_src->size);
+if (!sd_dst) {
+wipe_side_data(dst);
+return AVERROR(ENOMEM);
+}
+memcpy(sd_dst->data, sd_src->data, sd_src->size);
+} else {
+AVBufferRef *ref = av_buffer_ref(sd_src->buf);
+sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref);
+if (!sd_dst) {
+av_buffer_unref();
+wipe_side_data(dst);
+return AVERROR(ENOMEM);
+}
+}
+av_dict_copy(_dst->metadata, sd_src->metadata, 0);
+}
+return 0;
+}
+
 static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy)
 {
-int ret, i;
+int ret;
 
 dst->key_frame  = src->key_frame;
 dst->pict_type  = src->pict_type;
@@ -319,31 +355,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
 av_dict_copy(>metadata, src->metadata, 0);
 
-for (i = 0; i < src->nb_side_data; i++) {
-const AVFrameSideData *sd_src = src->side_data[i];
-AVFrameSideData *sd_dst;
-if (   sd_src->type == AV_FRAME_DATA_PANSCAN
-&& (src->width != dst->width || src->height != dst->height))
-continue;
-if (force_copy) {
-sd_dst = av_frame_new_side_data(dst, sd_src->type,
-sd_src->size);
-if (!sd_dst) {
-wipe_side_data(dst);
-return AVERROR(ENOMEM);
-}
-memcpy(sd_dst->data, sd_src->data, sd_src->size);
-} else {
-AVBufferRef *ref = av_buffer_ref(sd_src->buf);
-sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref);
-if (!sd_dst) {
-av_buffer_unref();
-wipe_side_data(dst);
-return AVERROR(ENOMEM);
-}
-}
-av_dict_copy(_dst->metadata, sd_src->metadata, 0);
-}
+if ((ret = av_frame_copy_side_data(dst, src,
+(force_copy ? AV_FRAME_TRANSFER_SD_COPY : 0) |
+AV_FRAME_TRANSFER_SD_FILTER) < 0))
+return ret;
 
 ret = av_buffer_replace(>opaque_ref, src->opaque_ref);
 ret |= av_buffer_replace(>private_ref, src->private_ref);
diff --git a/libavutil/frame.h b/libavutil/frame.h
index e60a82f6c0..5a3362fb55 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -861,6 +861,30 @@ int av_frame_copy(AVFrame *dst, const AVFrame *src);
  */
 int av_frame_copy_props(AVFrame *dst, const AVFrame *src);
 
+
+/**
+ * Copy side data, rather than creating new references.
+ */
+#define AV_FRAME_TRANSFER_SD_COPY  (1 << 0)
+/**
+ * Filter out side data that does not match dst properties.
+ */
+#define AV_FRAME_TRANSFER_SD_FILTER(1 << 1)
+
+/**
+ * Copy all side-data from src to dst.
+ *
+ * @param dst a frame to which the side data should be copied.
+ * @param src a frame from which to copy the side data.
+ * @param flags a combination of AV_FRAME_TRANSFER_SD_*
+ *
+ * @return 0 on success, a negative AVERROR on error.
+ *
+ * @note This function will create new references t

[FFmpeg-devel] [PATCH v2 2/2] ftools/opt_common: Print filter input/output formats in help output

2022-10-11 Thread softworkz
From: softworkz 

Exmaple command: ffmpeg -h filters=overlay

Output:

Filter overlay
  Overlay a video source on top of the input.
slice threading supported
Inputs:
   #0: main (video), Formats: Dynamic, Default: [yuv420p, yuvj420p,
  yuva420p, nv12, nv21]
   #1: overlay (video), Formats: Dynamic, Default: [yuva420p]
Outputs:
   #0: default (video), Formats: Dynamic, Default: [yuv420p, yuvj420p,
 yuva420p, nv12, nv21]

overlay AVOptions:
[...]

Signed-off-by: softworkz 
---
 fftools/opt_common.c | 37 ++---
 1 file changed, 26 insertions(+), 11 deletions(-)

diff --git a/fftools/opt_common.c b/fftools/opt_common.c
index 8a06df82df..774e3c776b 100644
--- a/fftools/opt_common.c
+++ b/fftools/opt_common.c
@@ -504,6 +504,7 @@ static void show_help_filter(const char *name)
 {
 #if CONFIG_AVFILTER
 const AVFilter *f = avfilter_get_by_name(name);
+AVBPrint bp;
 int i, count;
 
 if (!name) {
@@ -514,40 +515,54 @@ static void show_help_filter(const char *name)
 return;
 }
 
-printf("Filter %s\n", f->name);
+av_bprint_init(, 0, AV_BPRINT_SIZE_UNLIMITED);
+av_log_set_callback(NULL);
+
+av_bprintf(, "Filter %s\n", f->name);
 if (f->description)
-printf("  %s\n", f->description);
+av_bprintf(, "  %s\n", f->description);
 
 if (f->flags & AVFILTER_FLAG_SLICE_THREADS)
-printf("slice threading supported\n");
+av_bprintf(, "slice threading supported\n");
 
-printf("Inputs:\n");
+av_bprintf(, "Inputs:\n");
 count = avfilter_filter_pad_count(f, 0);
 for (i = 0; i < count; i++) {
-printf("   #%d: %s (%s)\n", i, avfilter_pad_get_name(f->inputs, i),
+av_bprintf(, "   #%d: %s (%s), Formats: ", i, 
avfilter_pad_get_name(f->inputs, i),
av_get_media_type_string(avfilter_pad_get_type(f->inputs, i)));
+
+avfilter_print_config_formats(, f, 0, i);
+av_bprintf(, "\n");
 }
 if (f->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)
-printf("dynamic (depending on the options)\n");
+av_bprintf(, "dynamic (depending on the options)\n");
 else if (!count)
-printf("none (source filter)\n");
+av_bprintf(, "none (source filter)\n");
 
-printf("Outputs:\n");
+av_bprintf(, "Outputs:\n");
 count = avfilter_filter_pad_count(f, 1);
 for (i = 0; i < count; i++) {
-printf("   #%d: %s (%s)\n", i, avfilter_pad_get_name(f->outputs, 
i),
+av_bprintf(, "   #%d: %s (%s), Formats: ", i, 
avfilter_pad_get_name(f->outputs, i),
av_get_media_type_string(avfilter_pad_get_type(f->outputs, i)));
+ 
+avfilter_print_config_formats(, f, 1, i);
+av_bprintf(, "\n");
 }
 if (f->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS)
-printf("dynamic (depending on the options)\n");
+av_bprintf(, "dynamic (depending on the options)\n");
 else if (!count)
-printf("none (sink filter)\n");
+av_bprintf(, "none (sink filter)\n");
+
+av_log_set_callback(log_callback_help);
+printf("%s\n", bp.str);
 
 if (f->priv_class)
 show_help_children(f->priv_class, AV_OPT_FLAG_VIDEO_PARAM | 
AV_OPT_FLAG_FILTERING_PARAM |
   AV_OPT_FLAG_AUDIO_PARAM);
 if (f->flags & AVFILTER_FLAG_SUPPORT_TIMELINE)
 printf("This filter has support for timeline through the 'enable' 
option.\n");
+
+av_bprint_finalize(, NULL);
 #else
 av_log(NULL, AV_LOG_ERROR, "Build without libavfilter; "
"can not to satisfy request\n");
-- 
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 1/2] avfilter/avfilter: add avfilter_print_config_formats()

2022-10-11 Thread softworkz
From: softworkz 

Prints the following to AVBPrint:

For pass-through filter links:

"All (passthrough)"

For filters using query_formats:

"Dynamic"

For filters using query_formats where a call to query_formats
succeeds (example):

"Dynamic, Defaults: [yuv420p, yuvj420p, yuva420p, nv12, nv21]"

For all other filters (example):

"[s16p, s32p, fltp, dblp]"

Except in case when the number of formats equals the number of
available formats:

"All"

Signed-off-by: softworkz 
---
 doc/APIchanges  |   3 ++
 libavfilter/avfilter.c  | 102 +++-
 libavfilter/avfilter.h  |  12 +
 libavfilter/avfiltergraph.c |  15 --
 libavfilter/internal.h  |   9 
 libavfilter/version.h   |   4 +-
 6 files changed, 137 insertions(+), 8 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 5807bf8069..82a029144d 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,9 @@ libavutil: 2021-04-27
 
 API changes, most recent first:
 
+2022-10-11 - xx - lavf 59.50.100 - avfilter.h
+  Add add avfilter_print_config_formats().
+  
 2022-10-11 - xx - lavu 57.39.101 - pixfmt.h
   Add AV_PIX_FMT_RGBF32 and AV_PIX_FMT_RGBAF32.
 
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index cc5505e65b..8f2741c6ec 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -196,6 +196,104 @@ void avfilter_link_free(AVFilterLink **link)
 av_freep(link);
 }
 
+static unsigned get_nb_pix_fmts(void)
+{
+unsigned i = 0;
+while (av_pix_fmt_desc_get(i++)) {}
+return i - 1;
+}
+
+static unsigned get_nb_sample_fmts(void)
+{
+unsigned i = 0;
+while (av_get_sample_fmt_name(i++)) {}
+return i - 1;
+}
+
+int avfilter_print_config_formats(AVBPrint *bp, const struct AVFilter *filter, 
int for_output, unsigned pad_index)
+{
+AVFilterGraph *graph;
+AVFilterContext *filter_context;
+AVFilterFormatsConfig *config;
+enum AVMediaType media_type;
+int ret = 0;
+
+if (filter->formats_state == FF_FILTER_FORMATS_PASSTHROUGH) {
+av_bprintf(bp, "All (passthrough)");
+return 0;
+}
+
+graph = avfilter_graph_alloc();
+if (!graph) {
+av_log(NULL, AV_LOG_ERROR, "Failed to create filtergraph\n");
+ret = AVERROR(ENOMEM);
+goto cleanup;
+}
+
+filter_context = avfilter_graph_alloc_filter(graph, filter, "filter");
+if (!filter_context) {
+av_log(NULL, AV_LOG_ERROR, "Failed to create filter\n");
+ret = AVERROR(ENOMEM);
+goto cleanup;
+}
+
+avfilter_init_str(filter_context, NULL);
+
+if (filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC)
+av_bprintf(bp, "Dynamic");
+
+if (!for_output && pad_index >= filter_context->nb_inputs 
+|| for_output && pad_index >= filter_context->nb_outputs)
+goto cleanup;
+
+avfilter_graph_config(graph, graph);
+
+for (unsigned i = 0; i < filter_context->nb_inputs; i++)
+filter_context->inputs[i] = (AVFilterLink 
*)av_mallocz(sizeof(AVFilterLink));
+
+for (unsigned i = 0; i < filter_context->nb_outputs; i++)
+filter_context->outputs[i] = (AVFilterLink 
*)av_mallocz(sizeof(AVFilterLink));
+
+ff_filter_query_formats(filter_context);
+
+config = for_output ? _context->outputs[pad_index]->incfg : 
_context->inputs[pad_index]->outcfg;
+
+if (!config || !config->formats)
+goto cleanup;
+
+media_type= for_output ? filter->outputs[pad_index].type : 
filter->inputs[pad_index].type;
+
+if (filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC) {
+if (config->formats && config->formats->nb_formats)
+av_bprintf(bp, ", Default: ");
+}
+
+if (config->formats == NULL)
+av_bprintf(bp, "unknown");
+else if (media_type == AVMEDIA_TYPE_VIDEO && config->formats->nb_formats 
== get_nb_pix_fmts() ||
+ media_type == AVMEDIA_TYPE_AUDIO && config->formats->nb_formats 
== get_nb_sample_fmts())
+av_bprintf(bp, "All");
+else {
+for (unsigned i = 0; i < config->formats->nb_formats; i++) {
+if (i == 0)
+av_bprintf(bp, "[");
+
+if (media_type == AVMEDIA_TYPE_VIDEO)
+av_bprintf(bp, "%s", 
av_get_pix_fmt_name(config->formats->formats[i]));
+else if (media_type == AVMEDIA_TYPE_AUDIO)
+av_bprintf(bp, "%s", 
av_get_sample_fmt_name(config->formats->formats[i]));
+
+if (i < config->formats->nb_formats - 1)
+av_bprintf(bp, ", ");
+else
+av_bprintf(bp, "]");}
+}
+
+c

[FFmpeg-devel] [PATCH 1/2] avfilter/avfilter: add avfilter_print_config_formats()

2022-10-11 Thread softworkz
From: softworkz 

Prints the following to AVBPrint:

For pass-through filter links:

"All (passthrough)"

For filters using query_formats:

"Dynamic"

For filters using query_formats where a call to query_formats
succeeds (example):

"Dynamic, Defaults: [yuv420p, yuvj420p, yuva420p, nv12, nv21]"

For all other filters (example):

"[s16p, s32p, fltp, dblp]"

Except in case when the number of formats equals the number of
available formats:

"All"

Signed-off-by: softworkz 
---
 doc/APIchanges  |   3 ++
 libavfilter/avfilter.c  | 102 +++-
 libavfilter/avfilter.h  |  12 +
 libavfilter/avfiltergraph.c |  14 +++--
 libavfilter/internal.h  |   9 
 libavfilter/version.h   |   4 +-
 6 files changed, 136 insertions(+), 8 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index cbb579612e..6e2a528b04 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,9 @@ libavutil: 2021-04-27
 
 API changes, most recent first:
 
+2022-10-11 - xx - lavf 59.50.100 - avfilter.h
+  Add add avfilter_print_config_formats().
+
 2022-10-05 - 37d5ddc317 - lavu 57.39.100 - cpu.h
   Add AV_CPU_FLAG_RVB_BASIC.
 
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index cc5505e65b..8cc665e19c 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -196,6 +196,104 @@ void avfilter_link_free(AVFilterLink **link)
 av_freep(link);
 }
 
+static unsigned get_nb_pix_fmts()
+{
+unsigned i = 0;
+while (av_pix_fmt_desc_get(i++)) {}
+return i - 1;
+}
+
+static unsigned get_nb_sample_fmts()
+{
+unsigned i = 0;
+while (av_get_sample_fmt_name(i++)) {}
+return i - 1;
+}
+
+int avfilter_print_config_formats(AVBPrint *bp, const struct AVFilter *filter, 
int for_output, unsigned pad_index)
+{
+AVFilterGraph *graph;
+AVFilterContext *filter_context;
+AVFilterFormatsConfig *config;
+enum AVMediaType media_type;
+int ret = 0;
+
+if (filter->formats_state == FF_FILTER_FORMATS_PASSTHROUGH) {
+av_bprintf(bp, "All (passthrough)");
+return 0;
+}
+
+graph = avfilter_graph_alloc();
+if (!graph) {
+av_log(NULL, AV_LOG_ERROR, "Failed to create filtergraph\n");
+ret = AVERROR(ENOMEM);
+goto cleanup;
+}
+
+filter_context = avfilter_graph_alloc_filter(graph, filter, "filter");
+if (!filter_context) {
+av_log(NULL, AV_LOG_ERROR, "Failed to create filter\n");
+ret = AVERROR(ENOMEM);
+goto cleanup;
+}
+
+avfilter_init_str(filter_context, NULL);
+
+if (filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC)
+av_bprintf(bp, "Dynamic");
+
+if (!for_output && pad_index >= filter_context->nb_inputs 
+|| for_output && pad_index >= filter_context->nb_outputs)
+goto cleanup;
+
+avfilter_graph_config(graph, graph);
+
+for (unsigned i = 0; i < filter_context->nb_inputs; i++)
+filter_context->inputs[i] = (AVFilterLink 
*)av_mallocz(sizeof(AVFilterLink));
+
+for (unsigned i = 0; i < filter_context->nb_outputs; i++)
+filter_context->outputs[i] = (AVFilterLink 
*)av_mallocz(sizeof(AVFilterLink));
+
+ff_filter_query_formats(filter_context);
+
+config = for_output ? _context->outputs[pad_index]->incfg : 
_context->inputs[pad_index]->outcfg;
+
+if (!config || !config->formats)
+goto cleanup;
+
+media_type= for_output ? filter->outputs[pad_index].type : 
filter->inputs[pad_index].type;
+
+if (filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC) {
+if (config->formats && config->formats->nb_formats)
+av_bprintf(bp, ", Default: ");
+}
+
+if (config->formats == NULL)
+av_bprintf(bp, "unknown");
+else if (media_type == AVMEDIA_TYPE_VIDEO && config->formats->nb_formats 
== get_nb_pix_fmts() ||
+ media_type == AVMEDIA_TYPE_AUDIO && config->formats->nb_formats 
== get_nb_sample_fmts())
+av_bprintf(bp, "All");
+else {
+for (unsigned i = 0; i < config->formats->nb_formats; i++) {
+if (i == 0)
+av_bprintf(bp, "[");
+
+if (media_type == AVMEDIA_TYPE_VIDEO)
+av_bprintf(bp, "%s", 
av_get_pix_fmt_name(config->formats->formats[i]));
+else if (media_type == AVMEDIA_TYPE_AUDIO)
+av_bprintf(bp, "%s", 
av_get_sample_fmt_name(config->formats->formats[i]));
+
+if (i < config->formats->nb_formats - 1)
+av_bprintf(bp, ", ");
+else
+av_bprintf(bp, "]");}
+}
+
+cleanup:
+avfilter_graph_free();
+

[FFmpeg-devel] [PATCH 2/2] ftools/opt_common: Print filter input/output formats in help output

2022-10-11 Thread softworkz
From: softworkz 

Exmaple command: ffmpeg -h filters=overlay

Output:

Filter overlay
  Overlay a video source on top of the input.
slice threading supported
Inputs:
   #0: main (video), Formats: Dynamic, Default: [yuv420p, yuvj420p,
  yuva420p, nv12, nv21]
   #1: overlay (video), Formats: Dynamic, Default: [yuva420p]
Outputs:
   #0: default (video), Formats: Dynamic, Default: [yuv420p, yuvj420p,
 yuva420p, nv12, nv21]

overlay AVOptions:
[...]

Signed-off-by: softworkz 
---
 fftools/opt_common.c | 39 +++
 1 file changed, 27 insertions(+), 12 deletions(-)

diff --git a/fftools/opt_common.c b/fftools/opt_common.c
index 8a06df82df..cb9de897a3 100644
--- a/fftools/opt_common.c
+++ b/fftools/opt_common.c
@@ -504,7 +504,8 @@ static void show_help_filter(const char *name)
 {
 #if CONFIG_AVFILTER
 const AVFilter *f = avfilter_get_by_name(name);
-int i, count;
+AVBPrint bp;
+int i, count, ret;
 
 if (!name) {
 av_log(NULL, AV_LOG_ERROR, "No filter name specified.\n");
@@ -514,40 +515,54 @@ static void show_help_filter(const char *name)
 return;
 }
 
-printf("Filter %s\n", f->name);
+av_bprint_init(, 0, AV_BPRINT_SIZE_UNLIMITED);
+av_log_set_callback(NULL);
+
+av_bprintf(, "Filter %s\n", f->name);
 if (f->description)
-printf("  %s\n", f->description);
+av_bprintf(, "  %s\n", f->description);
 
 if (f->flags & AVFILTER_FLAG_SLICE_THREADS)
-printf("slice threading supported\n");
+av_bprintf(, "slice threading supported\n");
 
-printf("Inputs:\n");
+av_bprintf(, "Inputs:\n");
 count = avfilter_filter_pad_count(f, 0);
 for (i = 0; i < count; i++) {
-printf("   #%d: %s (%s)\n", i, avfilter_pad_get_name(f->inputs, i),
+av_bprintf(, "   #%d: %s (%s), Formats: ", i, 
avfilter_pad_get_name(f->inputs, i),
av_get_media_type_string(avfilter_pad_get_type(f->inputs, i)));
+
+avfilter_print_config_formats(, f, 0, i);
+av_bprintf(, "\n");
 }
 if (f->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)
-printf("dynamic (depending on the options)\n");
+av_bprintf(, "dynamic (depending on the options)\n");
 else if (!count)
-printf("none (source filter)\n");
+av_bprintf(, "none (source filter)\n");
 
-printf("Outputs:\n");
+av_bprintf(, "Outputs:\n");
 count = avfilter_filter_pad_count(f, 1);
 for (i = 0; i < count; i++) {
-printf("   #%d: %s (%s)\n", i, avfilter_pad_get_name(f->outputs, 
i),
+av_bprintf(, "   #%d: %s (%s), Formats: ", i, 
avfilter_pad_get_name(f->outputs, i),
av_get_media_type_string(avfilter_pad_get_type(f->outputs, i)));
+ 
+avfilter_print_config_formats(, f, 1, i);
+av_bprintf(, "\n");
 }
 if (f->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS)
-printf("dynamic (depending on the options)\n");
+av_bprintf(, "dynamic (depending on the options)\n");
 else if (!count)
-printf("none (sink filter)\n");
+av_bprintf(, "none (sink filter)\n");
+
+av_log_set_callback(log_callback_help);
+printf("%s\n", bp.str);
 
 if (f->priv_class)
 show_help_children(f->priv_class, AV_OPT_FLAG_VIDEO_PARAM | 
AV_OPT_FLAG_FILTERING_PARAM |
   AV_OPT_FLAG_AUDIO_PARAM);
 if (f->flags & AVFILTER_FLAG_SUPPORT_TIMELINE)
 printf("This filter has support for timeline through the 'enable' 
option.\n");
+
+av_bprint_finalize(, NULL);
 #else
 av_log(NULL, AV_LOG_ERROR, "Build without libavfilter; "
"can not to satisfy request\n");
-- 
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 11/11] doc/filters.texi: update overlay_vaapi documentation

2022-10-10 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 doc/filters.texi | 49 +---
 1 file changed, 38 insertions(+), 11 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 2d0b5db909..5f4604a834 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -26271,30 +26271,57 @@ It takes two inputs and has one output. The first 
input is the "main" video on w
 The filter accepts the following options:
 
 @table @option
-
 @item x
-Set the x coordinate of the overlaid video on the main video.
-Default value is @code{0}.
-
 @item y
-Set the y coordinate of the overlaid video on the main video.
-Default value is @code{0}.
+Set expressions for the x and y coordinates of the overlaid video
+on the main video.
 
-@item w
-Set the width of the overlaid video on the main video.
-Default value is the width of input overlay video.
+Default value is "0" for both expressions.
 
+@item w
 @item h
-Set the height of the overlaid video on the main video.
-Default value is the height of input overlay video.
+Set expressions for the width and height the overlaid video
+on the main video.
+
+The expressions can contain the following parameters:
+
+@table @option
+
+@item main_w, W
+@item main_h, H
+The main input width and height.
+
+@item overlay_iw
+@item overlay_ih
+The overlay input width and height.
+
+@item overlay_w, w
+@item overlay_h, h
+The overlay output width and height.
+
+@item overlay_x, x
+@item overlay_y, y
+Position of the overlay layer inside of main
+
+@end table
 
 @item alpha
 Set transparency of overlaid video. Allowed range is 0.0 to 1.0.
 Higher value means lower transparency.
 Default value is @code{1.0}.
 
+@item eof_action
+See @ref{framesync}.
+
+@item shortest
+See @ref{framesync}.
+
+@item repeatlast
+See @ref{framesync}.
+
 @end table
 
+This filter also supports the @ref{framesync} options.
 @subsection Examples
 
 @itemize
-- 
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 10/11] doc/filters.texi: remove incorrect statement

2022-10-10 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 doc/filters.texi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 68205147f0..2d0b5db909 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -26267,7 +26267,6 @@ To use vaapi filters, you need to setup the vaapi 
device correctly. For more inf
 Overlay one video on the top of another.
 
 It takes two inputs and has one output. The first input is the "main" video on 
which the second input is overlaid.
-This filter requires same memory layout for all the inputs. So, format 
conversion may be needed.
 
 The filter accepts the following options:
 
-- 
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 09/11] avfilter/overlay_vaapi: enable expressions for overlay parameters

2022-10-10 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 141 +
 1 file changed, 127 insertions(+), 14 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index b2c254d9dd..7be7d52589 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -27,19 +27,106 @@
 #include "formats.h"
 #include "internal.h"
 #include "vaapi_vpp.h"
+#include "libavutil/eval.h"
+
+enum var_name {
+VAR_MAIN_iW, VAR_MW,
+VAR_MAIN_iH, VAR_MH,
+VAR_OVERLAY_iW,
+VAR_OVERLAY_iH,
+VAR_OVERLAY_X,  VAR_OX,
+VAR_OVERLAY_Y,  VAR_OY,
+VAR_OVERLAY_W,  VAR_OW,
+VAR_OVERLAY_H,  VAR_OH,
+VAR_VARS_NB
+};
 
 typedef struct OverlayVAAPIContext {
 VAAPIVPPContext  vpp_ctx; /**< must be the first field */
 FFFrameSync  fs;
-int  overlay_ox;
-int  overlay_oy;
-int  overlay_ow;
-int  overlay_oh;
+
+double   var_values[VAR_VARS_NB];
+char *overlay_ox;
+char *overlay_oy;
+char *overlay_ow;
+char *overlay_oh;
+int  ox;
+int  oy;
+int  ow;
+int  oh;
 floatalpha;
 unsigned int blend_flags;
 floatblend_alpha;
 } OverlayVAAPIContext;
 
+static const char *const var_names[] = {
+"main_w", "W",   /* input width of the main layer */
+"main_h", "H",   /* input height of the main layer */
+"overlay_iw",/* input width of the overlay layer */
+"overlay_ih",/* input height of the overlay layer */
+"overlay_x",  "x",   /* x position of the overlay layer inside of main */
+"overlay_y",  "y",   /* y position of the overlay layer inside of main */
+"overlay_w",  "w",   /* output width of overlay layer */
+"overlay_h",  "h",   /* output height of overlay layer */
+NULL
+};
+
+static int eval_expr(AVFilterContext *avctx)
+{
+OverlayVAAPIContext *ctx = avctx->priv;
+double   *var_values = ctx->var_values;
+int  ret = 0;
+AVExpr *ox_expr = NULL, *oy_expr = NULL;
+AVExpr *ow_expr = NULL, *oh_expr = NULL;
+
+#define PARSE_EXPR(e, s) {\
+ret = av_expr_parse(&(e), s, var_names, NULL, NULL, NULL, NULL, 0, ctx); \
+if (ret < 0) {\
+av_log(ctx, AV_LOG_ERROR, "Error when parsing '%s'.\n", s);\
+goto release;\
+}\
+}
+PARSE_EXPR(ox_expr, ctx->overlay_ox)
+PARSE_EXPR(oy_expr, ctx->overlay_oy)
+PARSE_EXPR(ow_expr, ctx->overlay_ow)
+PARSE_EXPR(oh_expr, ctx->overlay_oh)
+#undef PASS_EXPR
+
+var_values[VAR_OVERLAY_W] =
+var_values[VAR_OW]= av_expr_eval(ow_expr, var_values, NULL);
+var_values[VAR_OVERLAY_H] =
+var_values[VAR_OH]= av_expr_eval(oh_expr, var_values, NULL);
+
+/* calc again in case ow is relative to oh */
+var_values[VAR_OVERLAY_W] =
+var_values[VAR_OW]= av_expr_eval(ow_expr, var_values, NULL);
+
+var_values[VAR_OVERLAY_X] =
+var_values[VAR_OX]= av_expr_eval(ox_expr, var_values, NULL);
+var_values[VAR_OVERLAY_Y] =
+var_values[VAR_OY]= av_expr_eval(oy_expr, var_values, NULL);
+
+/* calc again in case ox is relative to oy */
+var_values[VAR_OVERLAY_X] =
+var_values[VAR_OX]= av_expr_eval(ox_expr, var_values, NULL);
+
+/* calc overlay_w and overlay_h again incase relative to ox,oy */
+var_values[VAR_OVERLAY_W] =
+var_values[VAR_OW]= av_expr_eval(ow_expr, var_values, NULL);
+var_values[VAR_OVERLAY_H] =
+var_values[VAR_OH]= av_expr_eval(oh_expr, var_values, NULL);
+var_values[VAR_OVERLAY_W] =
+var_values[VAR_OW]= av_expr_eval(ow_expr, var_values, NULL);
+
+release:
+av_expr_free(ox_expr);
+av_expr_free(oy_expr);
+av_expr_free(ow_expr);
+av_expr_free(oh_expr);
+
+return ret;
+}
+
 static int overlay_vaapi_build_filter_params(AVFilterContext *avctx)
 {
 VAAPIVPPContext *vpp_ctx   = avctx->priv;
@@ -233,10 +320,10 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
input_overlay->width, input_overlay->height, 
input_overlay->pts);
 
 overlay_region = (VARectangle) {
-.x  = ctx->overlay_ox,
-.y  = ctx->overlay_oy,
-.width  = ctx->overlay_ow ? ctx->overlay_ow : input_overlay->width,
-.height = ctx->overlay_oh ? ctx->overlay_oh : 
input_overlay->height,
+.x  = ctx->ox,
+.y  = ctx->oy,
+.width  = ctx->ow ? ctx->ow : input_overlay->width,
+.height = ctx-

[FFmpeg-devel] [PATCH 08/11] avfilter/overlay_vaapi: precalculate blend_state, enable pixel alpha

2022-10-10 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 44 --
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index f4f9cc58ec..b2c254d9dd 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -36,6 +36,8 @@ typedef struct OverlayVAAPIContext {
 int  overlay_ow;
 int  overlay_oh;
 floatalpha;
+unsigned int blend_flags;
+floatblend_alpha;
 } OverlayVAAPIContext;
 
 static int overlay_vaapi_build_filter_params(AVFilterContext *avctx)
@@ -246,8 +248,8 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
 
 memcpy(_params, , sizeof(subpic_params));
 
-blend_state.flags = VA_BLEND_GLOBAL_ALPHA;
-blend_state.global_alpha  = ctx->alpha;
+blend_state.flags = ctx->blend_flags;
+blend_state.global_alpha  = ctx->blend_alpha;
 subpic_params.blend_state = _state;
 
 subpic_params.surface   = 
(VASurfaceID)(uintptr_t)input_overlay->data[3];
@@ -269,6 +271,43 @@ fail:
 return err;
 }
 
+static int have_alpha_planar(AVFilterLink *link)
+{
+enum AVPixelFormat pix_fmt = link->format;
+const AVPixFmtDescriptor *desc;
+AVHWFramesContext *fctx;
+
+if (link->format == AV_PIX_FMT_VAAPI) {
+fctx= (AVHWFramesContext *)link->hw_frames_ctx->data;
+pix_fmt = fctx->sw_format;
+}
+
+desc = av_pix_fmt_desc_get(pix_fmt);
+if (!desc)
+return 0;
+
+return !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA);
+}
+
+static int overlay_vaapi_config_input_overlay(AVFilterLink *inlink)
+{
+AVFilterContext  *avctx  = inlink->dst;
+OverlayVAAPIContext *ctx = avctx->priv;
+
+ctx->blend_flags = 0;
+ctx->blend_alpha = 1.0f;
+
+if (ctx->alpha < 1.0f) {
+ctx->blend_flags |= VA_BLEND_GLOBAL_ALPHA;
+ctx->blend_alpha  = ctx->alpha;
+}
+
+if (have_alpha_planar(inlink))
+ctx->blend_flags |= VA_BLEND_PREMULTIPLIED_ALPHA;
+
+return 0;
+}
+
 static int overlay_vaapi_config_output(AVFilterLink *outlink)
 {
 AVFilterContext  *avctx  = outlink->src;
@@ -353,6 +392,7 @@ static const AVFilterPad overlay_vaapi_inputs[] = {
 {
 .name = "overlay",
 .type = AVMEDIA_TYPE_VIDEO,
+.config_props = overlay_vaapi_config_input_overlay,
 },
 };
 
-- 
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 07/11] avfilter/overlay_vaapi: add framesync options

2022-10-10 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index 71fc90a86b..f4f9cc58ec 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -292,8 +292,7 @@ static int overlay_vaapi_config_output(AVFilterLink 
*outlink)
 if (err < 0)
 return err;
 
-ctx->fs.on_event  = overlay_vaapi_blend;
-ctx->fs.opaque= ctx;
+ctx->fs.on_event = overlay_vaapi_blend;
 ctx->fs.time_base = outlink->time_base;
 
 return ff_framesync_configure(>fs);
@@ -321,6 +320,7 @@ static av_cold void overlay_vaapi_uninit(AVFilterContext 
*avctx)
 OverlayVAAPIContext *ctx = avctx->priv;
 
 ff_framesync_uninit(>fs);
+ff_vaapi_vpp_ctx_uninit(avctx);
 }
 
 #define OFFSET(x) offsetof(OverlayVAAPIContext, x)
@@ -331,10 +331,18 @@ static const AVOption overlay_vaapi_options[] = {
 { "w", "Overlay width",OFFSET(overlay_ow), AV_OPT_TYPE_INT,   
{ .i64 = 0 },   0, INT_MAX, .flags = FLAGS },
 { "h", "Overlay height",   OFFSET(overlay_oh), AV_OPT_TYPE_INT,   
{ .i64 = 0 },   0, INT_MAX, .flags = FLAGS },
 { "alpha", "Overlay global alpha", OFFSET(alpha),  AV_OPT_TYPE_FLOAT, 
{ .dbl = 1.0 }, 0.0, 1.0,   .flags = FLAGS },
+{ "eof_action", "Action to take when encountering EOF from secondary input 
",
+OFFSET(fs.opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT 
},
+EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, "eof_action" },
+{ "repeat", "Repeat the previous frame.",   0, AV_OPT_TYPE_CONST, { 
.i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, "eof_action" },
+{ "endall", "End both streams.",0, AV_OPT_TYPE_CONST, { 
.i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, "eof_action" },
+{ "pass",   "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { 
.i64 = EOF_ACTION_PASS },   .flags = FLAGS, "eof_action" },
+{ "shortest", "force termination when the shortest input terminates", 
OFFSET(fs.opt_shortest),   AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
+{ "repeatlast", "repeat overlay of the last overlay frame",   
OFFSET(fs.opt_repeatlast), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS },
 { NULL },
 };
 
-AVFILTER_DEFINE_CLASS(overlay_vaapi);
+FRAMESYNC_DEFINE_CLASS(overlay_vaapi, OverlayVAAPIContext, fs);
 
 static const AVFilterPad overlay_vaapi_inputs[] = {
 {
@@ -364,6 +372,7 @@ const AVFilter ff_vf_overlay_vaapi = {
 .init= _vaapi_init,
 .uninit  = _vaapi_uninit,
 .activate= _vaapi_activate,
+.preinit = overlay_vaapi_framesync_preinit,
 FILTER_INPUTS(overlay_vaapi_inputs),
 FILTER_OUTPUTS(overlay_vaapi_outputs),
 FILTER_SINGLE_PIXFMT(AV_PIX_FMT_VAAPI),
-- 
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 06/11] avfilter/overlay_vaapi: remove redundant .get_buffer assignments

2022-10-10 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index c14aacbb5d..71fc90a86b 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -340,13 +340,11 @@ static const AVFilterPad overlay_vaapi_inputs[] = {
 {
 .name = "main",
 .type = AVMEDIA_TYPE_VIDEO,
-.get_buffer.video = ff_default_get_video_buffer,
 .config_props = _vaapi_vpp_config_input,
 },
 {
 .name = "overlay",
 .type = AVMEDIA_TYPE_VIDEO,
-.get_buffer.video = ff_default_get_video_buffer,
 },
 };
 
-- 
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 05/11] avfilter/overlay_vaapi: reformat options

2022-10-10 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 15 +--
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index 1281038c36..c14aacbb5d 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -326,16 +326,11 @@ static av_cold void overlay_vaapi_uninit(AVFilterContext 
*avctx)
 #define OFFSET(x) offsetof(OverlayVAAPIContext, x)
 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
 static const AVOption overlay_vaapi_options[] = {
-{ "x", "Overlay x position",
-  OFFSET(overlay_ox), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = 
FLAGS },
-{ "y", "Overlay y position",
-  OFFSET(overlay_oy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = 
FLAGS },
-{ "w", "Overlay width",
-  OFFSET(overlay_ow), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = 
FLAGS },
-{ "h", "Overlay height",
-  OFFSET(overlay_oh), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = 
FLAGS },
-{ "alpha", "Overlay global alpha",
-  OFFSET(alpha), AV_OPT_TYPE_FLOAT, { .dbl = 1.0}, 0.0, 1.0, .flags = 
FLAGS},
+{ "x", "Overlay x position",   OFFSET(overlay_ox), AV_OPT_TYPE_INT,   
{ .i64 = 0 },   0, INT_MAX, .flags = FLAGS },
+{ "y", "Overlay y position",   OFFSET(overlay_oy), AV_OPT_TYPE_INT,   
{ .i64 = 0 },   0, INT_MAX, .flags = FLAGS },
+{ "w", "Overlay width",OFFSET(overlay_ow), AV_OPT_TYPE_INT,   
{ .i64 = 0 },   0, INT_MAX, .flags = FLAGS },
+{ "h", "Overlay height",   OFFSET(overlay_oh), AV_OPT_TYPE_INT,   
{ .i64 = 0 },   0, INT_MAX, .flags = FLAGS },
+{ "alpha", "Overlay global alpha", OFFSET(alpha),  AV_OPT_TYPE_FLOAT, 
{ .dbl = 1.0 }, 0.0, 1.0,   .flags = FLAGS },
 { NULL },
 };
 
-- 
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 04/11] avfilter/overlay_vaapi: handle secondary null input

2022-10-10 Thread softworkz
From: softworkz 

Currently segfaults in this case.

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 94 ++
 1 file changed, 49 insertions(+), 45 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index 66e736cce4..1281038c36 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -106,18 +106,6 @@ static int overlay_vaapi_render_picture(AVFilterContext 
*avctx,
params_id);
 
 
-vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
- VAProcPipelineParameterBufferType,
- sizeof(*subpic_params), 1, subpic_params, 
_params_id);
-if (vas != VA_STATUS_SUCCESS) {
-av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: "
-   "%d (%s).\n", vas, vaErrorStr(vas));
-err = AVERROR(EIO);
-goto fail_after_begin;
-}
-av_log(avctx, AV_LOG_DEBUG, "Pipeline subpic parameter buffer is %#x.\n",
-   subpic_params_id);
-
 vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
   _id, 1);
 if (vas != VA_STATUS_SUCCESS) {
@@ -127,13 +115,27 @@ static int overlay_vaapi_render_picture(AVFilterContext 
*avctx,
 goto fail_after_begin;
 }
 
-vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
-  _params_id, 1);
-if (vas != VA_STATUS_SUCCESS) {
-av_log(avctx, AV_LOG_ERROR, "Failed to render subpic parameter buffer: 
"
-   "%d (%s).\n", vas, vaErrorStr(vas));
-err = AVERROR(EIO);
-goto fail_after_begin;
+if (subpic_params) {
+vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
+ VAProcPipelineParameterBufferType,
+ sizeof(*subpic_params), 1, subpic_params, 
_params_id);
+if (vas != VA_STATUS_SUCCESS) {
+av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: "
+   "%d (%s).\n", vas, vaErrorStr(vas));
+err = AVERROR(EIO);
+goto fail_after_begin;
+}
+av_log(avctx, AV_LOG_DEBUG, "Pipeline subpic parameter buffer is 
%#x.\n",
+   subpic_params_id);
+
+vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
+  _params_id, 1);
+if (vas != VA_STATUS_SUCCESS) {
+av_log(avctx, AV_LOG_ERROR, "Failed to render subpic parameter 
buffer: "
+   "%d (%s).\n", vas, vaErrorStr(vas));
+err = AVERROR(EIO);
+goto fail_after_begin;
+}
 }
 
 vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
@@ -177,7 +179,7 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
 AVFrame *input_main, *input_overlay;
 AVFrame *output;
 VAProcPipelineParameterBuffer params, subpic_params;
-VABlendState blend_state; /**< Blend State */
+VABlendState blend_state = { 0 }; /**< Blend State */
 VARectangle overlay_region, output_region;
 int err;
 
@@ -192,10 +194,6 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
av_get_pix_fmt_name(input_main->format),
input_main->width, input_main->height, input_main->pts);
 
-av_log(avctx, AV_LOG_DEBUG, "Filter overlay: %s, %ux%u (%"PRId64").\n",
-   av_get_pix_fmt_name(input_overlay->format),
-   input_overlay->width, input_overlay->height, input_overlay->pts);
-
 if (vpp_ctx->va_context == VA_INVALID_ID)
 return AVERROR(EINVAL);
 
@@ -214,13 +212,6 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
 if (err < 0)
 goto fail;
 
-overlay_region = (VARectangle) {
-.x  = ctx->overlay_ox,
-.y  = ctx->overlay_oy,
-.width  = ctx->overlay_ow ? ctx->overlay_ow : input_overlay->width,
-.height = ctx->overlay_oh ? ctx->overlay_oh : input_overlay->height,
-};
-
 output_region = (VARectangle) {
 .x  = 0,
 .y  = 0,
@@ -228,29 +219,42 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
 .height = output->height,
 };
 
-if (overlay_region.x + overlay_region.width > input_main->width ||
-overlay_region.y + overlay_region.height > input_main->height) {
-av_log(ctx, AV_LOG_WARNING,
-   "The overlay image exceeds the scope of the main image, "
-   "will crop the overlay image according based on the main 
image.\n");
-}
-
 params.filters = _ctx->filter_buffers[0];
 params.num_filters = vpp_ctx->nb_filter_buffers;
 
 params.output_region = _region;
 params.output_background_color = VAAPI

[FFmpeg-devel] [PATCH 03/11] avfilter/overlay_vaapi: remove double framesync init

2022-10-10 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 31 +--
 1 file changed, 5 insertions(+), 26 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index cf17426b5d..66e736cce4 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -265,28 +265,6 @@ fail:
 return err;
 }
 
-static int overlay_vaapi_init_framesync(AVFilterContext *avctx)
-{
-OverlayVAAPIContext *ctx = avctx->priv;
-int ret, i;
-
-ctx->fs.on_event = overlay_vaapi_blend;
-ctx->fs.opaque   = ctx;
-ret = ff_framesync_init(>fs, avctx, avctx->nb_inputs);
-if (ret < 0)
-return ret;
-
-for (i = 0; i < avctx->nb_inputs; i++) {
-FFFrameSyncIn *in = >fs.in[i];
-in->before= EXT_STOP;
-in->after = EXT_INFINITY;
-in->sync  = i ? 1 : 2;
-in->time_base = avctx->inputs[i]->time_base;
-}
-
-return ff_framesync_configure(>fs);
-}
-
 static int overlay_vaapi_config_output(AVFilterLink *outlink)
 {
 AVFilterContext  *avctx  = outlink->src;
@@ -294,10 +272,7 @@ static int overlay_vaapi_config_output(AVFilterLink 
*outlink)
 VAAPIVPPContext *vpp_ctx = avctx->priv;
 int err;
 
-err = overlay_vaapi_init_framesync(avctx);
-if (err < 0)
-return err;
-
+outlink->time_base = avctx->inputs[0]->time_base;
 vpp_ctx->output_width  = avctx->inputs[0]->w;
 vpp_ctx->output_height = avctx->inputs[0]->h;
 
@@ -313,6 +288,10 @@ static int overlay_vaapi_config_output(AVFilterLink 
*outlink)
 if (err < 0)
 return err;
 
+ctx->fs.on_event  = overlay_vaapi_blend;
+ctx->fs.opaque= ctx;
+ctx->fs.time_base = outlink->time_base;
+
 return ff_framesync_configure(>fs);
 }
 
-- 
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 02/11] avfilter/overlay_vaapi: build filter params just once

2022-10-10 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index 218daf571f..cf17426b5d 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -181,10 +181,6 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
 VARectangle overlay_region, output_region;
 int err;
 
-err = overlay_vaapi_build_filter_params(avctx);
-if (err < 0)
-return err;
-
 err = ff_framesync_get_frame(fs, 0, _main, 0);
 if (err < 0)
 return err;
@@ -309,6 +305,10 @@ static int overlay_vaapi_config_output(AVFilterLink 
*outlink)
 if (err < 0)
 return err;
 
+err = overlay_vaapi_build_filter_params(avctx);
+if (err < 0)
+return err;
+
 err = ff_framesync_init_dualinput(>fs, avctx);
 if (err < 0)
 return err;
-- 
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 01/11] avfilter/overlay_vaapi: use FILTER_SINGLE_PIXFMT

2022-10-10 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_overlay_vaapi.c | 30 +-
 1 file changed, 1 insertion(+), 29 deletions(-)

diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
index 3e6a0de13f..218daf571f 100644
--- a/libavfilter/vf_overlay_vaapi.c
+++ b/libavfilter/vf_overlay_vaapi.c
@@ -38,34 +38,6 @@ typedef struct OverlayVAAPIContext {
 floatalpha;
 } OverlayVAAPIContext;
 
-static int overlay_vaapi_query_formats(AVFilterContext *ctx)
-{
-int ret;
-enum {
-MAIN= 0,
-OVERLAY = 1,
-};
-
-static const enum AVPixelFormat pix_fmts[] = {
-AV_PIX_FMT_VAAPI,
-AV_PIX_FMT_NONE
-};
-
-ret = ff_formats_ref(ff_make_format_list(pix_fmts), 
>inputs[MAIN]->outcfg.formats);
-if (ret < 0)
-return ret;
-
-ret = ff_formats_ref(ff_make_format_list(pix_fmts), 
>inputs[OVERLAY]->outcfg.formats);
-if (ret < 0)
-return ret;
-
-ret = ff_formats_ref(ff_make_format_list(pix_fmts), 
>outputs[0]->incfg.formats);
-if (ret < 0)
-return ret;
-
-return 0;
-}
-
 static int overlay_vaapi_build_filter_params(AVFilterContext *avctx)
 {
 VAAPIVPPContext *vpp_ctx   = avctx->priv;
@@ -418,6 +390,6 @@ const AVFilter ff_vf_overlay_vaapi = {
 .activate= _vaapi_activate,
 FILTER_INPUTS(overlay_vaapi_inputs),
 FILTER_OUTPUTS(overlay_vaapi_outputs),
-FILTER_QUERY_FUNC(overlay_vaapi_query_formats),
+FILTER_SINGLE_PIXFMT(AV_PIX_FMT_VAAPI),
 .flags_internal  = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
-- 
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 3/3] doc/fftools-common-opts: document log timing flags

2022-08-24 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 doc/fftools-common-opts.texi | 4 
 1 file changed, 4 insertions(+)

diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi
index d9145704d6..eee3b6ead0 100644
--- a/doc/fftools-common-opts.texi
+++ b/doc/fftools-common-opts.texi
@@ -201,6 +201,10 @@ and the "Last message repeated n times" line will be 
omitted.
 Indicates that log output should add a @code{[level]} prefix to each message
 line. This can be used as an alternative to log coloring, e.g. when dumping the
 log to file.
+@item timing
+Indicates that log lines should be prefixed with timing information.
+@item datetiming
+Indicates that log lines should be prefixed with date and timing information.
 @end table
 Flags can also be used alone by adding a '+'/'-' prefix to set/reset a single
 flag without affecting other @var{flags} or changing @var{loglevel}. When
-- 
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 2/3] fftools/opt_common: add timing and datetiming log flags

2022-08-24 Thread softworkz
From: softworkz 

This commit adds two logging flags: 'timing' and 'datetiming'.

Usage:

ffmpeg -loglevel +timing

or

ffmpeg -loglevel +datetiming

Signed-off-by: softworkz 
---
 fftools/opt_common.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/fftools/opt_common.c b/fftools/opt_common.c
index ae5e28a5af..bd8430751c 100644
--- a/fftools/opt_common.c
+++ b/fftools/opt_common.c
@@ -1268,6 +1268,18 @@ int opt_loglevel(void *optctx, const char *opt, const 
char *arg)
 } else {
 flags |= AV_LOG_PRINT_LEVEL;
 }
+} else if (av_strstart(token, "timing", )) {
+if (cmd == '-') {
+flags &= ~AV_LOG_PRINT_TIME;
+} else {
+flags |= AV_LOG_PRINT_TIME;
+}
+} else if (av_strstart(token, "datetiming", )) {
+if (cmd == '-') {
+flags &= ~AV_LOG_PRINT_DATETIME;
+} else {
+flags |= AV_LOG_PRINT_DATETIME;
+}
 } else {
 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 1/3] avutil/log: support logging of date and timing information

2022-08-24 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 doc/APIchanges  |  3 +++
 libavutil/log.c | 32 +---
 libavutil/log.h | 10 ++
 libavutil/version.h |  4 ++--
 4 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 4c0c9db628..eae5ba0525 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,9 @@ libavutil: 2021-04-27
 
 API changes, most recent first:
 
+2022-08-xx - xx - lavu 57.34.100 - log.h
+  Add flags AV_LOG_PRINT_TIME and AV_LOG_PRINT_DATETIME.
+
 2022-08-xx - xx - lavf 59 - avformat.h
   Deprecate av_stream_get_end_pts() without replacement.
 
diff --git a/libavutil/log.c b/libavutil/log.c
index 5948e50467..15a43c1631 100644
--- a/libavutil/log.c
+++ b/libavutil/log.c
@@ -42,6 +42,8 @@
 #include "internal.h"
 #include "log.h"
 #include "thread.h"
+#include "time.h"
+#include "time_internal.h"
 
 static AVMutex mutex = AV_MUTEX_INITIALIZER;
 
@@ -291,14 +293,32 @@ static const char *get_level_str(int level)
 }
 }
 
+static void format_date_now(AVBPrint* timeBuf, int include_date)
+{
+struct tm *ptm, tmbuf;
+const int64_t time_us = av_gettime();
+const int64_t time_ms = time_us / 1000;
+const time_t time_s   = time_ms / 1000;
+const int millisec= time_ms - (time_s * 1000);
+ptm   = localtime_r(_s, );
+if (ptm) {
+if (include_date)
+av_bprint_strftime(timeBuf, "%Y-%m-%d ", ptm);
+
+av_bprint_strftime(timeBuf, "%H:%M:%S", ptm);
+av_bprintf(timeBuf, ".%03d ", millisec);
+}
+}
+
 static void format_line(void *avcl, int level, const char *fmt, va_list vl,
-AVBPrint part[4], int *print_prefix, int type[2])
+AVBPrint part[5], int *print_prefix, int type[2])
 {
 AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
 av_bprint_init(part+0, 0, AV_BPRINT_SIZE_AUTOMATIC);
 av_bprint_init(part+1, 0, AV_BPRINT_SIZE_AUTOMATIC);
 av_bprint_init(part+2, 0, AV_BPRINT_SIZE_AUTOMATIC);
 av_bprint_init(part+3, 0, 65536);
+av_bprint_init(part+4, 0, AV_BPRINT_SIZE_AUTOMATIC);
 
 if(type) type[0] = type[1] = AV_CLASS_CATEGORY_NA + 16;
 if (*print_prefix && avc) {
@@ -316,6 +336,9 @@ static void format_line(void *avcl, int level, const char 
*fmt, va_list vl,
 if(type) type[1] = get_category(avcl);
 }
 
+if (*print_prefix && (flags & (AV_LOG_PRINT_TIME | AV_LOG_PRINT_DATETIME)))
+format_date_now([4], flags & AV_LOG_PRINT_DATETIME);
+
 if (*print_prefix && (level > AV_LOG_QUIET) && (flags & 
AV_LOG_PRINT_LEVEL))
 av_bprintf(part+2, "[%s] ", get_level_str(level));
 
@@ -336,7 +359,7 @@ void av_log_format_line(void *ptr, int level, const char 
*fmt, va_list vl,
 int av_log_format_line2(void *ptr, int level, const char *fmt, va_list vl,
 char *line, int line_size, int *print_prefix)
 {
-AVBPrint part[4];
+AVBPrint part[5];
 int ret;
 
 format_line(ptr, level, fmt, vl, part, print_prefix, NULL);
@@ -350,7 +373,7 @@ void av_log_default_callback(void* ptr, int level, const 
char* fmt, va_list vl)
 static int print_prefix = 1;
 static int count;
 static char prev[LINE_SZ];
-AVBPrint part[4];
+AVBPrint part[5];
 char line[LINE_SZ];
 static int is_atty;
 int type[2];
@@ -385,6 +408,9 @@ void av_log_default_callback(void* ptr, int level, const 
char* fmt, va_list vl)
 count = 0;
 }
 strcpy(prev, line);
+
+sanitize(part[4].str);
+colored_fputs(7, 0, part[4].str);
 sanitize(part[0].str);
 colored_fputs(type[0], 0, part[0].str);
 sanitize(part[1].str);
diff --git a/libavutil/log.h b/libavutil/log.h
index ab7ceabe22..8336f65b16 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -377,6 +377,16 @@ int av_log_format_line2(void *ptr, int level, const char 
*fmt, va_list vl,
  */
 #define AV_LOG_PRINT_LEVEL 2
 
+/**
+ * Include system time in log output.
+ */
+#define AV_LOG_PRINT_TIME 4
+
+/**
+ * Include system date and time in log output.
+ */
+#define AV_LOG_PRINT_DATETIME 8
+
 void av_log_set_flags(int arg);
 int av_log_get_flags(void);
 
diff --git a/libavutil/version.h b/libavutil/version.h
index 05661922b3..5d0df781cc 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,8 +79,8 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  57
-#define LIBAVUTIL_VERSION_MINOR  33
-#define LIBAVUTIL_VERSION_MICRO 101
+#define LIBAVUTIL_VERSION_MINOR  34
+#define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
LIBAVUTIL_VERSION_MINOR, \
-- 
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 4/4] avfilter/hwmap, hwupload: use new av_hwdevice_ctx_get_or_create_derived method

2022-07-21 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/vf_hwmap.c| 4 ++--
 libavfilter/vf_hwupload.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libavfilter/vf_hwmap.c b/libavfilter/vf_hwmap.c
index 2e03dfc1fe..b79cf6732c 100644
--- a/libavfilter/vf_hwmap.c
+++ b/libavfilter/vf_hwmap.c
@@ -82,8 +82,8 @@ static int hwmap_config_output(AVFilterLink *outlink)
 goto fail;
 }
 
-err = av_hwdevice_ctx_create_derived(, type,
- hwfc->device_ref, 0);
+err = av_hwdevice_ctx_get_or_create_derived(, type,
+hwfc->device_ref, 0);
 if (err < 0) {
 av_log(avctx, AV_LOG_ERROR, "Failed to created derived "
"device context: %d.\n", err);
diff --git a/libavfilter/vf_hwupload.c b/libavfilter/vf_hwupload.c
index dbc41734cc..41ee0e43c4 100644
--- a/libavfilter/vf_hwupload.c
+++ b/libavfilter/vf_hwupload.c
@@ -51,7 +51,7 @@ static int hwupload_query_formats(AVFilterContext *avctx)
 /* We already have a specified device. */
 } else if (avctx->hw_device_ctx) {
 if (ctx->device_type) {
-err = av_hwdevice_ctx_create_derived(
+err = av_hwdevice_ctx_get_or_create_derived(
 >hwdevice_ref,
 av_hwdevice_find_type_by_name(ctx->device_type),
 avctx->hw_device_ctx, 0);
-- 
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 3/4] lavu: bump minor version and add doc/APIchanges entry for av_hwdevice_ctx_get_or_create_derived()

2022-07-21 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 doc/APIchanges  | 6 ++
 libavutil/version.h | 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index b3563cd528..ba21f60953 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,12 @@ libavutil: 2021-04-27
 
 API changes, most recent first:
 
+2022-07-01 - xx - lavu 57.31.100 - hwcontext.h
+  Add av_hwdevice_ctx_get_or_create_derived().
+
+2022-07-01 - xx - lavu 57.31.100 - buffer.h
+  Add av_ref_from_buffer().
+
 2022-07-xx - xx - lavu 57.30.100 - frame.h
   Add AVFrame.duration, deprecate AVFrame.pkt_duration.
 
diff --git a/libavutil/version.h b/libavutil/version.h
index ee4c531b80..e9eefcdb2c 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,7 +79,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  57
-#define LIBAVUTIL_VERSION_MINOR  30
+#define LIBAVUTIL_VERSION_MINOR  31
 #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 2/4] avutils/hwcontext: add derive-device function which searches for existing devices in both directions

2022-07-21 Thread softworkz
From: softworkz 

The test /libavutil/tests/hwdevice checks that when deriving a device
from a source device and then deriving back to the type of the source
device, the result is matching the original source device, i.e. the
derivation mechanism doesn't create a new device in this case.

Previously, this test was usually passed, but only due to two different
kind of flaws:

1. The test covers only a single level of derivation (and back)

It derives device Y from device X and then Y back to the type of X and
checks whether the result matches X.

What it doesn't check for, are longer chains of derivation like:

CUDA1 > OpenCL2 > CUDA3 and then back to OpenCL4

In that case, the second derivation returns the first device (CUDA3 ==
CUDA1), but when deriving OpenCL4, hwcontext.c was creating a new
OpenCL4 context instead of returning OpenCL2, because there was no link
from CUDA1 to OpenCL2 (only backwards from OpenCL2 to CUDA1)

If the test would check for two levels of derivation, it would have
failed.

This patch fixes those (yet untested) cases by introducing forward
references (derived_device) in addition to the existing back references
(source_device).

2. hwcontext_qsv didn't properly set the source_device

In case of QSV, hwcontext_qsv creates a source context internally
(vaapi, dxva2 or d3d11va) without calling av_hwdevice_ctx_create_derived
and without setting source_device.

This way, the hwcontext test ran successful, but what practically
happened, was that - for example - deriving vaapi from qsv didn't return
the original underlying vaapi device and a new one was created instead:
Exactly what the test is intended to detect and prevent. It just
couldn't do so, because the original device was hidden (= not set as the
source_device of the QSV device).

This patch properly makes these setting and fixes all derivation
scenarios.

(at a later stage, /libavutil/tests/hwdevice should be extended to check
longer derivation chains as well)

Signed-off-by: softworkz 
---
 libavutil/hwcontext.c  | 167 +++--
 libavutil/hwcontext.h  |  20 
 libavutil/hwcontext_internal.h |  11 +++
 libavutil/hwcontext_qsv.c  |  11 ++-
 4 files changed, 199 insertions(+), 10 deletions(-)

diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c
index ab9ad3703e..43e39cb2d3 100644
--- a/libavutil/hwcontext.c
+++ b/libavutil/hwcontext.c
@@ -22,12 +22,17 @@
 #include "buffer.h"
 #include "common.h"
 #include "hwcontext.h"
+
+#include 
+
+#include "buffer_internal.h"
 #include "hwcontext_internal.h"
 #include "imgutils.h"
 #include "log.h"
 #include "mem.h"
 #include "pixdesc.h"
 #include "pixfmt.h"
+#include "thread.h"
 
 static const HWContextType * const hw_table[] = {
 #if CONFIG_CUDA
@@ -80,6 +85,84 @@ static const char *const hw_type_names[] = {
 [AV_HWDEVICE_TYPE_VULKAN] = "vulkan",
 };
 
+#define DEVICE_REGISTRY_SIZE 1024
+
+static AVMutex mutex;
+static int is_mutex_initialized = 0;
+static int max_device_reg_id = 1;
+static AVBuffer *hw_device_registry[DEVICE_REGISTRY_SIZE];
+
+static int register_hw_device(const AVBufferRef *ref)
+{
+AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data;
+const int reg_id = max_device_reg_id;
+
+if (ctx == NULL)
+return AVERROR(EINVAL);
+
+if (!is_mutex_initialized) {
+int ret;
+ret = ff_mutex_init(, NULL);
+if (ret) {
+av_log(ctx, AV_LOG_ERROR, "hwcontext: mutex initialization failed! 
Error code: %d\n", ret);
+return AVERROR(EINVAL);
+}
+
+is_mutex_initialized = 1;
+}
+
+ff_mutex_lock();
+
+for (int i = 0; i < max_device_reg_id; ++i) {
+if (hw_device_registry[i] != NULL && hw_device_registry[i] == 
ref->buffer) {
+ff_mutex_unlock();
+return i;
+}
+}
+
+if (max_device_reg_id >= DEVICE_REGISTRY_SIZE) {
+ff_mutex_unlock();
+av_log(ctx, AV_LOG_ERROR, "Device registry limit (%d) reached. Please 
check for excessive device creation.", DEVICE_REGISTRY_SIZE);
+return AVERROR(ENOMEM);
+}
+
+hw_device_registry[reg_id] = ref->buffer;
+max_device_reg_id++;
+
+ff_mutex_unlock();
+
+return reg_id;
+}
+
+static void unregister_hw_device(const AVHWDeviceContext *ctx)
+{
+if (ctx == NULL || !is_mutex_initialized)
+return;
+
+ff_mutex_lock();
+
+hw_device_registry[ctx->internal->registered_device_id] = NULL;
+
+ff_mutex_unlock();
+}
+
+static AVBufferRef *get_registered_hw_device(int registered_id)
+{
+if (registered_id <= 0 || registered_id >= max_device_reg_id)
+return NULL;
+
+ff_mutex_lock();
+
+if (hw_device_registry[registered_id] != NULL && 
hw_device_registry[registered_id]->data != NULL) {
+AVBufferRef *ref =

[FFmpeg-devel] [PATCH v3 1/4] avutil/buffer: add av_ref_from_buffer() function

2022-07-21 Thread softworkz
From: softworkz 

This allows to create AVBufferRef from AVBuffer directly.

Signed-off-by: softworkz 
---
 libavutil/buffer.c | 16 
 libavutil/buffer.h |  8 
 2 files changed, 24 insertions(+)

diff --git a/libavutil/buffer.c b/libavutil/buffer.c
index 54590be566..f9df0ad6ea 100644
--- a/libavutil/buffer.c
+++ b/libavutil/buffer.c
@@ -100,6 +100,22 @@ AVBufferRef *av_buffer_allocz(size_t size)
 return ret;
 }
 
+AVBufferRef *av_ref_from_buffer(AVBuffer *buf)
+{
+AVBufferRef *ref = av_mallocz(sizeof(*ref));
+
+if (!ref)
+return NULL;
+
+ref->buffer = buf;
+ref->data   = buf->data;
+ref->size   = buf->size;
+
+atomic_fetch_add_explicit(>refcount, 1, memory_order_relaxed);
+
+return ref;
+}
+
 AVBufferRef *av_buffer_ref(const AVBufferRef *buf)
 {
 AVBufferRef *ret = av_mallocz(sizeof(*ret));
diff --git a/libavutil/buffer.h b/libavutil/buffer.h
index e1ef5b7f07..491734b9ca 100644
--- a/libavutil/buffer.h
+++ b/libavutil/buffer.h
@@ -139,6 +139,14 @@ AVBufferRef *av_buffer_create(uint8_t *data, size_t size,
  */
 void av_buffer_default_free(void *opaque, uint8_t *data);
 
+/**
+ * Create a new reference to an AVBuffer.
+ *
+ * @return a new AVBufferRef referring to the same AVBuffer as buf or NULL on
+ * failure.
+ */
+AVBufferRef *av_ref_from_buffer(AVBuffer *buf);
+
 /**
  * Create a new reference to an AVBuffer.
  *
-- 
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 v5 3/6] avcodec/mpeg12dec: make mpeg_decode_user_data() accessible

2022-07-01 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/mpeg12.h| 28 
 libavcodec/mpeg12dec.c | 40 +---
 2 files changed, 33 insertions(+), 35 deletions(-)

diff --git a/libavcodec/mpeg12.h b/libavcodec/mpeg12.h
index e0406b32d9..84a829cdd3 100644
--- a/libavcodec/mpeg12.h
+++ b/libavcodec/mpeg12.h
@@ -23,6 +23,7 @@
 #define AVCODEC_MPEG12_H
 
 #include "mpegvideo.h"
+#include "libavutil/stereo3d.h"
 
 /* Start codes. */
 #define SEQ_END_CODE0x01b7
@@ -34,6 +35,31 @@
 #define EXT_START_CODE  0x01b5
 #define USER_START_CODE 0x01b2
 
+typedef struct Mpeg1Context {
+MpegEncContext mpeg_enc_ctx;
+int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
+int repeat_field;   /* true if we must repeat the field */
+AVPanScan pan_scan; /* some temporary storage for the panscan */
+AVStereo3D stereo3d;
+int has_stereo3d;
+AVBufferRef *a53_buf_ref;
+uint8_t afd;
+int has_afd;
+int slice_count;
+unsigned aspect_ratio_info;
+AVRational save_aspect;
+int save_width, save_height, save_progressive_seq;
+int rc_buffer_size;
+AVRational frame_rate_ext;  /* MPEG-2 specific framerate modificator */
+unsigned frame_rate_index;
+int sync;   /* Did we reach a sync point like a 
GOP/SEQ/KEYFrame? */
+int closed_gop;
+int tmpgexs;
+int first_slice;
+int extradata_decoded;
+int64_t timecode_frame_start;  /*< GOP timecode frame start number, in non 
drop frame format */
+} Mpeg1Context;
+
 void ff_mpeg12_common_init(MpegEncContext *s);
 
 void ff_mpeg1_clean_buffers(MpegEncContext *s);
@@ -45,4 +71,6 @@ void ff_mpeg12_find_best_frame_rate(AVRational frame_rate,
 int *code, int *ext_n, int *ext_d,
 int nonstandard);
 
+void ff_mpeg_decode_user_data(AVCodecContext *avctx, Mpeg1Context *s1, const 
uint8_t *p, int buf_size);
+
 #endif /* AVCODEC_MPEG12_H */
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index e9bde48f7a..11d2b58185 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -58,31 +58,6 @@
 
 #define A53_MAX_CC_COUNT 2000
 
-typedef struct Mpeg1Context {
-MpegEncContext mpeg_enc_ctx;
-int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
-int repeat_field;   /* true if we must repeat the field */
-AVPanScan pan_scan; /* some temporary storage for the panscan */
-AVStereo3D stereo3d;
-int has_stereo3d;
-AVBufferRef *a53_buf_ref;
-uint8_t afd;
-int has_afd;
-int slice_count;
-unsigned aspect_ratio_info;
-AVRational save_aspect;
-int save_width, save_height, save_progressive_seq;
-int rc_buffer_size;
-AVRational frame_rate_ext;  /* MPEG-2 specific framerate modificator */
-unsigned frame_rate_index;
-int sync;   /* Did we reach a sync point like a 
GOP/SEQ/KEYFrame? */
-int closed_gop;
-int tmpgexs;
-int first_slice;
-int extradata_decoded;
-int64_t timecode_frame_start;  /*< GOP timecode frame start number, in non 
drop frame format */
-} Mpeg1Context;
-
 #define MB_TYPE_ZERO_MV   0x2000
 
 static const uint32_t ptype2mb_type[7] = {
@@ -2198,11 +2173,9 @@ static int vcr2_init_sequence(AVCodecContext *avctx)
 return 0;
 }
 
-static int mpeg_decode_a53_cc(AVCodecContext *avctx,
+static int mpeg_decode_a53_cc(AVCodecContext *avctx, Mpeg1Context *s1,
   const uint8_t *p, int buf_size)
 {
-Mpeg1Context *s1 = avctx->priv_data;
-
 if (buf_size >= 6 &&
 p[0] == 'G' && p[1] == 'A' && p[2] == '9' && p[3] == '4' &&
 p[4] == 3 && (p[5] & 0x40)) {
@@ -2333,12 +2306,9 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx,
 return 0;
 }
 
-static void mpeg_decode_user_data(AVCodecContext *avctx,
-  const uint8_t *p, int buf_size)
+void ff_mpeg_decode_user_data(AVCodecContext *avctx, Mpeg1Context *s1, const 
uint8_t *p, int buf_size)
 {
-Mpeg1Context *s = avctx->priv_data;
 const uint8_t *buf_end = p + buf_size;
-Mpeg1Context *s1 = avctx->priv_data;
 
 #if 0
 int i;
@@ -2352,7 +2322,7 @@ static void mpeg_decode_user_data(AVCodecContext *avctx,
 int i;
 for(i=0; i<20; i++)
 if (!memcmp(p+i, "\0TMPGEXS\0", 9)){
-s->tmpgexs= 1;
+s1->tmpgexs= 1;
 }
 }
 /* we parse the DTG active format information */
@@ -2398,7 +2368,7 @@ static void mpeg_decode_user_data(AVCodecContext *avctx,
 break;
 }
 }
-} else if (mpeg_decode_a53_cc(avctx, p, buf_size)) {
+} else if (mpeg_decode_a53_cc(avctx, s1, p, buf_size)) {
 

[FFmpeg-devel] [PATCH v5 6/6] avcodec/qsvdec: Implement SEI parsing for QSV decoders

2022-07-01 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/Makefile  |   6 +-
 libavcodec/hevcdsp.c |   4 +
 libavcodec/qsvdec.c  | 234 +++
 3 files changed, 243 insertions(+), 1 deletion(-)

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 3b8f7b5e01..7b98391745 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -144,7 +144,11 @@ OBJS-$(CONFIG_MSS34DSP)+= mss34dsp.o
 OBJS-$(CONFIG_PIXBLOCKDSP) += pixblockdsp.o
 OBJS-$(CONFIG_QPELDSP) += qpeldsp.o
 OBJS-$(CONFIG_QSV) += qsv.o
-OBJS-$(CONFIG_QSVDEC)  += qsvdec.o
+OBJS-$(CONFIG_QSVDEC)  += qsvdec.o h264_slice.o h264_cabac.o 
h264_cavlc.o \
+  h264_direct.o h264_mb.o 
h264_picture.o h264_loopfilter.o \
+  h264dec.o h264_refs.o cabac.o 
hevcdec.o hevc_refs.o \
+   
  hevc_filter.o hevc_cabac.o hevc_mvs.o hevcpred.o hevcdsp.o \
+   
  h274.o dovi_rpu.o mpeg12dec.o
 OBJS-$(CONFIG_QSVENC)  += qsvenc.o
 OBJS-$(CONFIG_RANGECODER)  += rangecoder.o
 OBJS-$(CONFIG_RDFT)+= rdft.o
diff --git a/libavcodec/hevcdsp.c b/libavcodec/hevcdsp.c
index 2ca551df1d..c7a436d30f 100644
--- a/libavcodec/hevcdsp.c
+++ b/libavcodec/hevcdsp.c
@@ -22,6 +22,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config_components.h"
+
 #include "hevcdsp.h"
 
 static const int8_t transform[32][32] = {
@@ -257,6 +259,7 @@ int i = 0;
 break;
 }
 
+#if CONFIG_HEVC_DECODER
 #if ARCH_AARCH64
 ff_hevc_dsp_init_aarch64(hevcdsp, bit_depth);
 #elif ARCH_ARM
@@ -270,4 +273,5 @@ int i = 0;
 #elif ARCH_LOONGARCH
 ff_hevc_dsp_init_loongarch(hevcdsp, bit_depth);
 #endif
+#endif
 }
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 5fc5bed4c8..e854f363ec 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -49,6 +49,12 @@
 #include "hwconfig.h"
 #include "qsv.h"
 #include "qsv_internal.h"
+#include "h264dec.h"
+#include "h264_sei.h"
+#include "hevcdec.h"
+#include "hevc_ps.h"
+#include "hevc_sei.h"
+#include "mpeg12.h"
 
 static const AVRational mfx_tb = { 1, 9 };
 
@@ -60,6 +66,8 @@ static const AVRational mfx_tb = { 1, 9 };
 AV_NOPTS_VALUE : pts_tb.num ? \
 av_rescale_q(mfx_pts, mfx_tb, pts_tb) : mfx_pts)
 
+#define PAYLOAD_BUFFER_SIZE 65535
+
 typedef struct QSVAsyncFrame {
 mfxSyncPoint *sync;
 QSVFrame *frame;
@@ -101,6 +109,9 @@ typedef struct QSVContext {
 
 mfxExtBuffer **ext_buffers;
 int nb_ext_buffers;
+
+mfxU8 payload_buffer[PAYLOAD_BUFFER_SIZE];
+Mpeg1Context mpeg_ctx;
 } QSVContext;
 
 static const AVCodecHWConfigInternal *const qsv_hw_configs[] = {
@@ -599,6 +610,210 @@ static int qsv_export_film_grain(AVCodecContext *avctx, 
mfxExtAV1FilmGrainParam
 return 0;
 }
 #endif
+static int find_start_offset(mfxU8 data[4])
+{
+if (data[0] == 0 && data[1] == 0 && data[2] == 1)
+return 3;
+
+if (data[0] == 0 && data[1] == 0 && data[2] == 0 && data[3] == 1)
+return 4;
+
+return 0;
+}
+
+static int parse_sei_h264(AVCodecContext* avctx, QSVContext* q, AVFrame* out)
+{
+H264SEIContext sei = { 0 };
+GetBitContext gb = { 0 };
+mfxPayload payload = { 0, .Data = >payload_buffer[0], .BufSize = 
sizeof(q->payload_buffer) };
+mfxU64 ts;
+int ret;
+
+while (1) {
+int start;
+memset(payload.Data, 0, payload.BufSize);
+
+ret = MFXVideoDECODE_GetPayload(q->session, , );
+if (ret == MFX_ERR_NOT_ENOUGH_BUFFER) {
+av_log(avctx, AV_LOG_WARNING, "Warning: Insufficient buffer on 
GetPayload(). Size: %"PRIu64" Needed: %d\n", sizeof(q->payload_buffer), 
payload.BufSize);
+return 0;
+}
+if (ret != MFX_ERR_NONE)
+return ret;
+
+if (payload.NumBit == 0 || payload.NumBit >= payload.BufSize * 8)
+break;
+
+start = find_start_offset(payload.Data);
+
+switch (payload.Type) {
+case SEI_TYPE_BUFFERING_PERIOD:
+case SEI_TYPE_PIC_TIMING:
+continue;
+}
+
+if (init_get_bits(, [start], payload.NumBit - start * 
8) < 0)
+av_log(avctx, AV_LOG_ERROR, "Error initializing bitstream reader 
SEI type: %d  Numbits %d error: %d\n", payload.Type, payload.NumBit, ret);
+else {
+ret = ff_h264_sei_decode(, , NULL, avctx);
+
+if (ret < 0)
+av_log(avctx, AV_LOG_WARNING, "Failed to parse

[FFmpeg-devel] [PATCH v5 2/6] avcodec/vpp_qsv: Copy side data from input to output frame

2022-07-01 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/qsvvpp.c |  6 ++
 libavfilter/vf_overlay_qsv.c | 19 +++
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
index 954f882637..f4bf628073 100644
--- a/libavfilter/qsvvpp.c
+++ b/libavfilter/qsvvpp.c
@@ -843,6 +843,12 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink 
*inlink, AVFrame *picr
 return AVERROR(EAGAIN);
 break;
 }
+
+av_frame_remove_all_side_data(out_frame->frame);
+ret = av_frame_copy_side_data(out_frame->frame, in_frame->frame, 0);
+if (ret < 0)
+return ret;
+
 out_frame->frame->pts = av_rescale_q(out_frame->surface.Data.TimeStamp,
  default_tb, outlink->time_base);
 
diff --git a/libavfilter/vf_overlay_qsv.c b/libavfilter/vf_overlay_qsv.c
index 7e76b39aa9..e15214dbf2 100644
--- a/libavfilter/vf_overlay_qsv.c
+++ b/libavfilter/vf_overlay_qsv.c
@@ -231,13 +231,24 @@ static int process_frame(FFFrameSync *fs)
 {
 AVFilterContext  *ctx = fs->parent;
 QSVOverlayContext  *s = fs->opaque;
+AVFrame   *frame0 = NULL;
 AVFrame*frame = NULL;
-int   ret = 0, i;
+int   ret = 0;
 
-for (i = 0; i < ctx->nb_inputs; i++) {
+for (unsigned i = 0; i < ctx->nb_inputs; i++) {
 ret = ff_framesync_get_frame(fs, i, , 0);
-if (ret == 0)
-ret = ff_qsvvpp_filter_frame(s->qsv, ctx->inputs[i], frame);
+
+if (ret == 0) {
+if (i == 0)
+frame0 = frame;
+else {
+av_frame_remove_all_side_data(frame);
+ret = av_frame_copy_side_data(frame, frame0, 0);
+}
+
+ret = ret < 0 ? ret : ff_qsvvpp_filter_frame(s->qsv, 
ctx->inputs[i], frame);
+}
+
 if (ret < 0 && ret != AVERROR(EAGAIN))
 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 v5 1/6] avutil/frame: Add av_frame_copy_side_data() and av_frame_remove_all_side_data()

2022-07-01 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
Signed-off-by: Anton Khirnov 
---
 doc/APIchanges  |  4 +++
 libavutil/frame.c   | 67 +++--
 libavutil/frame.h   | 32 ++
 libavutil/version.h |  2 +-
 4 files changed, 78 insertions(+), 27 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 20b944933a..6b5bf61d85 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,10 @@ libavutil: 2021-04-27
 
 API changes, most recent first:
 
+2022-05-26 - x - lavu 57.28.100 - frame.h
+  Add av_frame_remove_all_side_data(), av_frame_copy_side_data(),
+  AV_FRAME_TRANSFER_SD_COPY, and AV_FRAME_TRANSFER_SD_FILTER.
+
 2022-06-12 - xx - lavf 59.25.100 - avio.h
   Add avio_vprintf(), similar to avio_printf() but allow to use it
   from within a function taking a variable argument list as input.
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 4c16488c66..5d34fde904 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -271,9 +271,45 @@ FF_ENABLE_DEPRECATION_WARNINGS
 return AVERROR(EINVAL);
 }
 
+void av_frame_remove_all_side_data(AVFrame *frame)
+{
+wipe_side_data(frame);
+}
+
+int av_frame_copy_side_data(AVFrame* dst, const AVFrame* src, int flags)
+{
+for (unsigned i = 0; i < src->nb_side_data; i++) {
+const AVFrameSideData *sd_src = src->side_data[i];
+AVFrameSideData *sd_dst;
+if ((flags & AV_FRAME_TRANSFER_SD_FILTER) &&
+sd_src->type == AV_FRAME_DATA_PANSCAN &&
+(src->width != dst->width || src->height != dst->height))
+continue;
+if (flags & AV_FRAME_TRANSFER_SD_COPY) {
+sd_dst = av_frame_new_side_data(dst, sd_src->type,
+sd_src->size);
+if (!sd_dst) {
+wipe_side_data(dst);
+return AVERROR(ENOMEM);
+}
+memcpy(sd_dst->data, sd_src->data, sd_src->size);
+} else {
+AVBufferRef *ref = av_buffer_ref(sd_src->buf);
+sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref);
+if (!sd_dst) {
+av_buffer_unref();
+wipe_side_data(dst);
+return AVERROR(ENOMEM);
+}
+}
+av_dict_copy(_dst->metadata, sd_src->metadata, 0);
+}
+return 0;
+}
+
 static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy)
 {
-int ret, i;
+int ret;
 
 dst->key_frame  = src->key_frame;
 dst->pict_type  = src->pict_type;
@@ -309,31 +345,10 @@ static int frame_copy_props(AVFrame *dst, const AVFrame 
*src, int force_copy)
 
 av_dict_copy(>metadata, src->metadata, 0);
 
-for (i = 0; i < src->nb_side_data; i++) {
-const AVFrameSideData *sd_src = src->side_data[i];
-AVFrameSideData *sd_dst;
-if (   sd_src->type == AV_FRAME_DATA_PANSCAN
-&& (src->width != dst->width || src->height != dst->height))
-continue;
-if (force_copy) {
-sd_dst = av_frame_new_side_data(dst, sd_src->type,
-sd_src->size);
-if (!sd_dst) {
-wipe_side_data(dst);
-return AVERROR(ENOMEM);
-}
-memcpy(sd_dst->data, sd_src->data, sd_src->size);
-} else {
-AVBufferRef *ref = av_buffer_ref(sd_src->buf);
-sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref);
-if (!sd_dst) {
-av_buffer_unref();
-wipe_side_data(dst);
-return AVERROR(ENOMEM);
-}
-}
-av_dict_copy(_dst->metadata, sd_src->metadata, 0);
-}
+if ((ret = av_frame_copy_side_data(dst, src,
+(force_copy ? AV_FRAME_TRANSFER_SD_COPY : 0) |
+AV_FRAME_TRANSFER_SD_FILTER) < 0))
+return ret;
 
 ret = av_buffer_replace(>opaque_ref, src->opaque_ref);
 ret |= av_buffer_replace(>private_ref, src->private_ref);
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 33fac2054c..f72b6fae71 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -850,6 +850,30 @@ int av_frame_copy(AVFrame *dst, const AVFrame *src);
  */
 int av_frame_copy_props(AVFrame *dst, const AVFrame *src);
 
+
+/**
+ * Copy side data, rather than creating new references.
+ */
+#define AV_FRAME_TRANSFER_SD_COPY  (1 << 0)
+/**
+ * Filter out side data that does not match dst properties.
+ */
+#define AV_FRAME_TRANSFER_SD_FILTER(1 << 1)
+
+/**
+ * Copy all side-data from src to dst.
+ *
+ * @param dst a frame to which the side data should be copied.
+ * @param src a frame from which to copy the side data.
+ * @param flags a combination 

[FFmpeg-devel] [PATCH v5 5/6] avcodec/h264dec: make h264_export_frame_props() accessible

2022-07-01 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/h264_slice.c | 98 +
 libavcodec/h264dec.h|  2 +
 2 files changed, 52 insertions(+), 48 deletions(-)

diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index d56722a5c2..f2a4c1c657 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1157,11 +1157,10 @@ static int h264_init_ps(H264Context *h, const 
H264SliceContext *sl, int first_sl
 return 0;
 }
 
-static int h264_export_frame_props(H264Context *h)
+int ff_h264_export_frame_props(AVCodecContext *logctx, H264SEIContext *sei, 
H264Context *h, AVFrame *out)
 {
-const SPS *sps = h->ps.sps;
-H264Picture *cur = h->cur_pic_ptr;
-AVFrame *out = cur->f;
+const SPS *sps = h ? h->ps.sps : NULL;
+H264Picture *cur = h ? h->cur_pic_ptr : NULL;
 
 out->interlaced_frame = 0;
 out->repeat_pict  = 0;
@@ -1169,19 +1168,19 @@ static int h264_export_frame_props(H264Context *h)
 /* Signal interlacing information externally. */
 /* Prioritize picture timing SEI information over used
  * decoding process if it exists. */
-if (h->sei.picture_timing.present) {
-int ret = ff_h264_sei_process_picture_timing(>sei.picture_timing, 
sps,
- h->avctx);
+if (sps && sei->picture_timing.present) {
+int ret = ff_h264_sei_process_picture_timing(>picture_timing, sps,
+ logctx);
 if (ret < 0) {
-av_log(h->avctx, AV_LOG_ERROR, "Error processing a picture timing 
SEI\n");
-if (h->avctx->err_recognition & AV_EF_EXPLODE)
+av_log(logctx, AV_LOG_ERROR, "Error processing a picture timing 
SEI\n");
+if (logctx->err_recognition & AV_EF_EXPLODE)
 return ret;
-h->sei.picture_timing.present = 0;
+sei->picture_timing.present = 0;
 }
 }
 
-if (sps->pic_struct_present_flag && h->sei.picture_timing.present) {
-H264SEIPictureTiming *pt = >sei.picture_timing;
+if (h && sps && sps->pic_struct_present_flag && 
sei->picture_timing.present) {
+H264SEIPictureTiming *pt = >picture_timing;
 switch (pt->pic_struct) {
 case H264_SEI_PIC_STRUCT_FRAME:
 break;
@@ -1215,21 +1214,23 @@ static int h264_export_frame_props(H264Context *h)
 if ((pt->ct_type & 3) &&
 pt->pic_struct <= H264_SEI_PIC_STRUCT_BOTTOM_TOP)
 out->interlaced_frame = (pt->ct_type & (1 << 1)) != 0;
-} else {
+} else if (h) {
 /* Derive interlacing flag from used decoding process. */
 out->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h);
 }
-h->prev_interlaced_frame = out->interlaced_frame;
 
-if (cur->field_poc[0] != cur->field_poc[1]) {
+if (h)
+h->prev_interlaced_frame = out->interlaced_frame;
+
+if (sps && cur->field_poc[0] != cur->field_poc[1]) {
 /* Derive top_field_first from field pocs. */
 out->top_field_first = cur->field_poc[0] < cur->field_poc[1];
-} else {
-if (sps->pic_struct_present_flag && h->sei.picture_timing.present) {
+} else if (sps) {
+if (sps->pic_struct_present_flag && sei->picture_timing.present) {
 /* Use picture timing SEI information. Even if it is a
  * information of a past frame, better than nothing. */
-if (h->sei.picture_timing.pic_struct == 
H264_SEI_PIC_STRUCT_TOP_BOTTOM ||
-h->sei.picture_timing.pic_struct == 
H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP)
+if (sei->picture_timing.pic_struct == 
H264_SEI_PIC_STRUCT_TOP_BOTTOM ||
+sei->picture_timing.pic_struct == 
H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP)
 out->top_field_first = 1;
 else
 out->top_field_first = 0;
@@ -1243,11 +1244,11 @@ static int h264_export_frame_props(H264Context *h)
 }
 }
 
-if (h->sei.frame_packing.present &&
-h->sei.frame_packing.arrangement_type <= 6 &&
-h->sei.frame_packing.content_interpretation_type > 0 &&
-h->sei.frame_packing.content_interpretation_type < 3) {
-H264SEIFramePacking *fp = >sei.frame_packing;
+if (sei->frame_packing.present &&
+sei->frame_packing.arrangement_type <= 6 &&
+sei->frame_packing.content_interpretation_type > 0 &&
+sei->frame_packing.content_interpretation_type < 3) {
+H264SEIFramePacking *fp = >frame_packing;
 AVStereo3D *stereo = av_stereo3d_create_s

[FFmpeg-devel] [PATCH v5 4/6] avcodec/hevcdec: make set_side_data() accessible

2022-07-01 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/hevcdec.c | 117 +--
 libavcodec/hevcdec.h |   9 
 2 files changed, 67 insertions(+), 59 deletions(-)

diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index e84c30dd13..b4d8db8c6b 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -2726,23 +2726,22 @@ error:
 return res;
 }
 
-static int set_side_data(HEVCContext *s)
+int ff_hevc_set_side_data(AVCodecContext *logctx, HEVCSEI *sei, HEVCContext 
*s, AVFrame *out)
 {
-AVFrame *out = s->ref->frame;
-int ret;
+int ret = 0;
 
-if (s->sei.frame_packing.present &&
-s->sei.frame_packing.arrangement_type >= 3 &&
-s->sei.frame_packing.arrangement_type <= 5 &&
-s->sei.frame_packing.content_interpretation_type > 0 &&
-s->sei.frame_packing.content_interpretation_type < 3) {
+if (sei->frame_packing.present &&
+sei->frame_packing.arrangement_type >= 3 &&
+sei->frame_packing.arrangement_type <= 5 &&
+sei->frame_packing.content_interpretation_type > 0 &&
+sei->frame_packing.content_interpretation_type < 3) {
 AVStereo3D *stereo = av_stereo3d_create_side_data(out);
 if (!stereo)
 return AVERROR(ENOMEM);
 
-switch (s->sei.frame_packing.arrangement_type) {
+switch (sei->frame_packing.arrangement_type) {
 case 3:
-if (s->sei.frame_packing.quincunx_subsampling)
+if (sei->frame_packing.quincunx_subsampling)
 stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
 else
 stereo->type = AV_STEREO3D_SIDEBYSIDE;
@@ -2755,21 +2754,21 @@ static int set_side_data(HEVCContext *s)
 break;
 }
 
-if (s->sei.frame_packing.content_interpretation_type == 2)
+if (sei->frame_packing.content_interpretation_type == 2)
 stereo->flags = AV_STEREO3D_FLAG_INVERT;
 
-if (s->sei.frame_packing.arrangement_type == 5) {
-if (s->sei.frame_packing.current_frame_is_frame0_flag)
+if (sei->frame_packing.arrangement_type == 5) {
+if (sei->frame_packing.current_frame_is_frame0_flag)
 stereo->view = AV_STEREO3D_VIEW_LEFT;
 else
 stereo->view = AV_STEREO3D_VIEW_RIGHT;
 }
 }
 
-if (s->sei.display_orientation.present &&
-(s->sei.display_orientation.anticlockwise_rotation ||
- s->sei.display_orientation.hflip || 
s->sei.display_orientation.vflip)) {
-double angle = s->sei.display_orientation.anticlockwise_rotation * 360 
/ (double) (1 << 16);
+if (sei->display_orientation.present &&
+(sei->display_orientation.anticlockwise_rotation ||
+ sei->display_orientation.hflip || sei->display_orientation.vflip)) {
+double angle = sei->display_orientation.anticlockwise_rotation * 360 / 
(double) (1 << 16);
 AVFrameSideData *rotation = av_frame_new_side_data(out,

AV_FRAME_DATA_DISPLAYMATRIX,
sizeof(int32_t) * 
9);
@@ -2788,17 +2787,17 @@ static int set_side_data(HEVCContext *s)
* (1 - 2 * !!s->sei.display_orientation.vflip);
 av_display_rotation_set((int32_t *)rotation->data, angle);
 av_display_matrix_flip((int32_t *)rotation->data,
-   s->sei.display_orientation.hflip,
-   s->sei.display_orientation.vflip);
+   sei->display_orientation.hflip,
+   sei->display_orientation.vflip);
 }
 
 // Decrement the mastering display flag when IRAP frame has 
no_rasl_output_flag=1
 // so the side data persists for the entire coded video sequence.
-if (s->sei.mastering_display.present > 0 &&
+if (s && sei->mastering_display.present > 0 &&
 IS_IRAP(s) && s->no_rasl_output_flag) {
-s->sei.mastering_display.present--;
+sei->mastering_display.present--;
 }
-if (s->sei.mastering_display.present) {
+if (sei->mastering_display.present) {
 // HEVC uses a g,b,r ordering, which we convert to a more natural r,g,b
 const int mapping[3] = {2, 0, 1};
 const int chroma_den = 5;
@@ -2811,25 +2810,25 @@ static int set_side_data(HEVCContext *s)
 
 for (i = 0; i < 3; i++) {
 const int j = mapping[i];
-metadata->display_primaries[i][0].num = 
s->sei.mastering_display.display_primaries[j][0];
+metadata->display_primaries[i][0].num 

[FFmpeg-devel] [PATCH v4 3/6] avcodec/mpeg12dec: make mpeg_decode_user_data() accessible

2022-06-26 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/mpeg12.h| 28 
 libavcodec/mpeg12dec.c | 40 +---
 2 files changed, 33 insertions(+), 35 deletions(-)

diff --git a/libavcodec/mpeg12.h b/libavcodec/mpeg12.h
index e0406b32d9..84a829cdd3 100644
--- a/libavcodec/mpeg12.h
+++ b/libavcodec/mpeg12.h
@@ -23,6 +23,7 @@
 #define AVCODEC_MPEG12_H
 
 #include "mpegvideo.h"
+#include "libavutil/stereo3d.h"
 
 /* Start codes. */
 #define SEQ_END_CODE0x01b7
@@ -34,6 +35,31 @@
 #define EXT_START_CODE  0x01b5
 #define USER_START_CODE 0x01b2
 
+typedef struct Mpeg1Context {
+MpegEncContext mpeg_enc_ctx;
+int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
+int repeat_field;   /* true if we must repeat the field */
+AVPanScan pan_scan; /* some temporary storage for the panscan */
+AVStereo3D stereo3d;
+int has_stereo3d;
+AVBufferRef *a53_buf_ref;
+uint8_t afd;
+int has_afd;
+int slice_count;
+unsigned aspect_ratio_info;
+AVRational save_aspect;
+int save_width, save_height, save_progressive_seq;
+int rc_buffer_size;
+AVRational frame_rate_ext;  /* MPEG-2 specific framerate modificator */
+unsigned frame_rate_index;
+int sync;   /* Did we reach a sync point like a 
GOP/SEQ/KEYFrame? */
+int closed_gop;
+int tmpgexs;
+int first_slice;
+int extradata_decoded;
+int64_t timecode_frame_start;  /*< GOP timecode frame start number, in non 
drop frame format */
+} Mpeg1Context;
+
 void ff_mpeg12_common_init(MpegEncContext *s);
 
 void ff_mpeg1_clean_buffers(MpegEncContext *s);
@@ -45,4 +71,6 @@ void ff_mpeg12_find_best_frame_rate(AVRational frame_rate,
 int *code, int *ext_n, int *ext_d,
 int nonstandard);
 
+void ff_mpeg_decode_user_data(AVCodecContext *avctx, Mpeg1Context *s1, const 
uint8_t *p, int buf_size);
+
 #endif /* AVCODEC_MPEG12_H */
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index e9bde48f7a..11d2b58185 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -58,31 +58,6 @@
 
 #define A53_MAX_CC_COUNT 2000
 
-typedef struct Mpeg1Context {
-MpegEncContext mpeg_enc_ctx;
-int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
-int repeat_field;   /* true if we must repeat the field */
-AVPanScan pan_scan; /* some temporary storage for the panscan */
-AVStereo3D stereo3d;
-int has_stereo3d;
-AVBufferRef *a53_buf_ref;
-uint8_t afd;
-int has_afd;
-int slice_count;
-unsigned aspect_ratio_info;
-AVRational save_aspect;
-int save_width, save_height, save_progressive_seq;
-int rc_buffer_size;
-AVRational frame_rate_ext;  /* MPEG-2 specific framerate modificator */
-unsigned frame_rate_index;
-int sync;   /* Did we reach a sync point like a 
GOP/SEQ/KEYFrame? */
-int closed_gop;
-int tmpgexs;
-int first_slice;
-int extradata_decoded;
-int64_t timecode_frame_start;  /*< GOP timecode frame start number, in non 
drop frame format */
-} Mpeg1Context;
-
 #define MB_TYPE_ZERO_MV   0x2000
 
 static const uint32_t ptype2mb_type[7] = {
@@ -2198,11 +2173,9 @@ static int vcr2_init_sequence(AVCodecContext *avctx)
 return 0;
 }
 
-static int mpeg_decode_a53_cc(AVCodecContext *avctx,
+static int mpeg_decode_a53_cc(AVCodecContext *avctx, Mpeg1Context *s1,
   const uint8_t *p, int buf_size)
 {
-Mpeg1Context *s1 = avctx->priv_data;
-
 if (buf_size >= 6 &&
 p[0] == 'G' && p[1] == 'A' && p[2] == '9' && p[3] == '4' &&
 p[4] == 3 && (p[5] & 0x40)) {
@@ -2333,12 +2306,9 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx,
 return 0;
 }
 
-static void mpeg_decode_user_data(AVCodecContext *avctx,
-  const uint8_t *p, int buf_size)
+void ff_mpeg_decode_user_data(AVCodecContext *avctx, Mpeg1Context *s1, const 
uint8_t *p, int buf_size)
 {
-Mpeg1Context *s = avctx->priv_data;
 const uint8_t *buf_end = p + buf_size;
-Mpeg1Context *s1 = avctx->priv_data;
 
 #if 0
 int i;
@@ -2352,7 +2322,7 @@ static void mpeg_decode_user_data(AVCodecContext *avctx,
 int i;
 for(i=0; i<20; i++)
 if (!memcmp(p+i, "\0TMPGEXS\0", 9)){
-s->tmpgexs= 1;
+s1->tmpgexs= 1;
 }
 }
 /* we parse the DTG active format information */
@@ -2398,7 +2368,7 @@ static void mpeg_decode_user_data(AVCodecContext *avctx,
 break;
 }
 }
-} else if (mpeg_decode_a53_cc(avctx, p, buf_size)) {
+} else if (mpeg_decode_a53_cc(avctx, s1, p, buf_size)) {
 

[FFmpeg-devel] [PATCH v4 2/6] avcodec/vpp_qsv: Copy side data from input to output frame

2022-06-26 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavfilter/qsvvpp.c |  6 ++
 libavfilter/vf_overlay_qsv.c | 19 +++
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
index 954f882637..f4bf628073 100644
--- a/libavfilter/qsvvpp.c
+++ b/libavfilter/qsvvpp.c
@@ -843,6 +843,12 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink 
*inlink, AVFrame *picr
 return AVERROR(EAGAIN);
 break;
 }
+
+av_frame_remove_all_side_data(out_frame->frame);
+ret = av_frame_copy_side_data(out_frame->frame, in_frame->frame, 0);
+if (ret < 0)
+return ret;
+
 out_frame->frame->pts = av_rescale_q(out_frame->surface.Data.TimeStamp,
  default_tb, outlink->time_base);
 
diff --git a/libavfilter/vf_overlay_qsv.c b/libavfilter/vf_overlay_qsv.c
index 7e76b39aa9..e15214dbf2 100644
--- a/libavfilter/vf_overlay_qsv.c
+++ b/libavfilter/vf_overlay_qsv.c
@@ -231,13 +231,24 @@ static int process_frame(FFFrameSync *fs)
 {
 AVFilterContext  *ctx = fs->parent;
 QSVOverlayContext  *s = fs->opaque;
+AVFrame   *frame0 = NULL;
 AVFrame*frame = NULL;
-int   ret = 0, i;
+int   ret = 0;
 
-for (i = 0; i < ctx->nb_inputs; i++) {
+for (unsigned i = 0; i < ctx->nb_inputs; i++) {
 ret = ff_framesync_get_frame(fs, i, , 0);
-if (ret == 0)
-ret = ff_qsvvpp_filter_frame(s->qsv, ctx->inputs[i], frame);
+
+if (ret == 0) {
+if (i == 0)
+frame0 = frame;
+else {
+av_frame_remove_all_side_data(frame);
+ret = av_frame_copy_side_data(frame, frame0, 0);
+}
+
+ret = ret < 0 ? ret : ff_qsvvpp_filter_frame(s->qsv, 
ctx->inputs[i], frame);
+}
+
 if (ret < 0 && ret != AVERROR(EAGAIN))
 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 v4 1/6] avutil/frame: Add av_frame_copy_side_data() and av_frame_remove_all_side_data()

2022-06-26 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
Signed-off-by: Anton Khirnov 
---
 doc/APIchanges  |  4 +++
 libavutil/frame.c   | 67 +++--
 libavutil/frame.h   | 32 ++
 libavutil/version.h |  2 +-
 4 files changed, 78 insertions(+), 27 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 20b944933a..6b5bf61d85 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,10 @@ libavutil: 2021-04-27
 
 API changes, most recent first:
 
+2022-05-26 - x - lavu 57.28.100 - frame.h
+  Add av_frame_remove_all_side_data(), av_frame_copy_side_data(),
+  AV_FRAME_TRANSFER_SD_COPY, and AV_FRAME_TRANSFER_SD_FILTER.
+
 2022-06-12 - xx - lavf 59.25.100 - avio.h
   Add avio_vprintf(), similar to avio_printf() but allow to use it
   from within a function taking a variable argument list as input.
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 4c16488c66..5d34fde904 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -271,9 +271,45 @@ FF_ENABLE_DEPRECATION_WARNINGS
 return AVERROR(EINVAL);
 }
 
+void av_frame_remove_all_side_data(AVFrame *frame)
+{
+wipe_side_data(frame);
+}
+
+int av_frame_copy_side_data(AVFrame* dst, const AVFrame* src, int flags)
+{
+for (unsigned i = 0; i < src->nb_side_data; i++) {
+const AVFrameSideData *sd_src = src->side_data[i];
+AVFrameSideData *sd_dst;
+if ((flags & AV_FRAME_TRANSFER_SD_FILTER) &&
+sd_src->type == AV_FRAME_DATA_PANSCAN &&
+(src->width != dst->width || src->height != dst->height))
+continue;
+if (flags & AV_FRAME_TRANSFER_SD_COPY) {
+sd_dst = av_frame_new_side_data(dst, sd_src->type,
+sd_src->size);
+if (!sd_dst) {
+wipe_side_data(dst);
+return AVERROR(ENOMEM);
+}
+memcpy(sd_dst->data, sd_src->data, sd_src->size);
+} else {
+AVBufferRef *ref = av_buffer_ref(sd_src->buf);
+sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref);
+if (!sd_dst) {
+av_buffer_unref();
+wipe_side_data(dst);
+return AVERROR(ENOMEM);
+}
+}
+av_dict_copy(_dst->metadata, sd_src->metadata, 0);
+}
+return 0;
+}
+
 static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy)
 {
-int ret, i;
+int ret;
 
 dst->key_frame  = src->key_frame;
 dst->pict_type  = src->pict_type;
@@ -309,31 +345,10 @@ static int frame_copy_props(AVFrame *dst, const AVFrame 
*src, int force_copy)
 
 av_dict_copy(>metadata, src->metadata, 0);
 
-for (i = 0; i < src->nb_side_data; i++) {
-const AVFrameSideData *sd_src = src->side_data[i];
-AVFrameSideData *sd_dst;
-if (   sd_src->type == AV_FRAME_DATA_PANSCAN
-&& (src->width != dst->width || src->height != dst->height))
-continue;
-if (force_copy) {
-sd_dst = av_frame_new_side_data(dst, sd_src->type,
-sd_src->size);
-if (!sd_dst) {
-wipe_side_data(dst);
-return AVERROR(ENOMEM);
-}
-memcpy(sd_dst->data, sd_src->data, sd_src->size);
-} else {
-AVBufferRef *ref = av_buffer_ref(sd_src->buf);
-sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref);
-if (!sd_dst) {
-av_buffer_unref();
-wipe_side_data(dst);
-return AVERROR(ENOMEM);
-}
-}
-av_dict_copy(_dst->metadata, sd_src->metadata, 0);
-}
+if ((ret = av_frame_copy_side_data(dst, src,
+(force_copy ? AV_FRAME_TRANSFER_SD_COPY : 0) |
+AV_FRAME_TRANSFER_SD_FILTER) < 0))
+return ret;
 
 ret = av_buffer_replace(>opaque_ref, src->opaque_ref);
 ret |= av_buffer_replace(>private_ref, src->private_ref);
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 33fac2054c..f72b6fae71 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -850,6 +850,30 @@ int av_frame_copy(AVFrame *dst, const AVFrame *src);
  */
 int av_frame_copy_props(AVFrame *dst, const AVFrame *src);
 
+
+/**
+ * Copy side data, rather than creating new references.
+ */
+#define AV_FRAME_TRANSFER_SD_COPY  (1 << 0)
+/**
+ * Filter out side data that does not match dst properties.
+ */
+#define AV_FRAME_TRANSFER_SD_FILTER(1 << 1)
+
+/**
+ * Copy all side-data from src to dst.
+ *
+ * @param dst a frame to which the side data should be copied.
+ * @param src a frame from which to copy the side data.
+ * @param flags a combination 

[FFmpeg-devel] [PATCH v4 6/6] avcodec/qsvdec: Implement SEI parsing for QSV decoders

2022-06-26 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/qsvdec.c | 234 
 1 file changed, 234 insertions(+)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 5fc5bed4c8..e854f363ec 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -49,6 +49,12 @@
 #include "hwconfig.h"
 #include "qsv.h"
 #include "qsv_internal.h"
+#include "h264dec.h"
+#include "h264_sei.h"
+#include "hevcdec.h"
+#include "hevc_ps.h"
+#include "hevc_sei.h"
+#include "mpeg12.h"
 
 static const AVRational mfx_tb = { 1, 9 };
 
@@ -60,6 +66,8 @@ static const AVRational mfx_tb = { 1, 9 };
 AV_NOPTS_VALUE : pts_tb.num ? \
 av_rescale_q(mfx_pts, mfx_tb, pts_tb) : mfx_pts)
 
+#define PAYLOAD_BUFFER_SIZE 65535
+
 typedef struct QSVAsyncFrame {
 mfxSyncPoint *sync;
 QSVFrame *frame;
@@ -101,6 +109,9 @@ typedef struct QSVContext {
 
 mfxExtBuffer **ext_buffers;
 int nb_ext_buffers;
+
+mfxU8 payload_buffer[PAYLOAD_BUFFER_SIZE];
+Mpeg1Context mpeg_ctx;
 } QSVContext;
 
 static const AVCodecHWConfigInternal *const qsv_hw_configs[] = {
@@ -599,6 +610,210 @@ static int qsv_export_film_grain(AVCodecContext *avctx, 
mfxExtAV1FilmGrainParam
 return 0;
 }
 #endif
+static int find_start_offset(mfxU8 data[4])
+{
+if (data[0] == 0 && data[1] == 0 && data[2] == 1)
+return 3;
+
+if (data[0] == 0 && data[1] == 0 && data[2] == 0 && data[3] == 1)
+return 4;
+
+return 0;
+}
+
+static int parse_sei_h264(AVCodecContext* avctx, QSVContext* q, AVFrame* out)
+{
+H264SEIContext sei = { 0 };
+GetBitContext gb = { 0 };
+mfxPayload payload = { 0, .Data = >payload_buffer[0], .BufSize = 
sizeof(q->payload_buffer) };
+mfxU64 ts;
+int ret;
+
+while (1) {
+int start;
+memset(payload.Data, 0, payload.BufSize);
+
+ret = MFXVideoDECODE_GetPayload(q->session, , );
+if (ret == MFX_ERR_NOT_ENOUGH_BUFFER) {
+av_log(avctx, AV_LOG_WARNING, "Warning: Insufficient buffer on 
GetPayload(). Size: %"PRIu64" Needed: %d\n", sizeof(q->payload_buffer), 
payload.BufSize);
+return 0;
+}
+if (ret != MFX_ERR_NONE)
+return ret;
+
+if (payload.NumBit == 0 || payload.NumBit >= payload.BufSize * 8)
+break;
+
+start = find_start_offset(payload.Data);
+
+switch (payload.Type) {
+case SEI_TYPE_BUFFERING_PERIOD:
+case SEI_TYPE_PIC_TIMING:
+continue;
+}
+
+if (init_get_bits(, [start], payload.NumBit - start * 
8) < 0)
+av_log(avctx, AV_LOG_ERROR, "Error initializing bitstream reader 
SEI type: %d  Numbits %d error: %d\n", payload.Type, payload.NumBit, ret);
+else {
+ret = ff_h264_sei_decode(, , NULL, avctx);
+
+if (ret < 0)
+av_log(avctx, AV_LOG_WARNING, "Failed to parse SEI type: %d  
Numbits %d error: %d\n", payload.Type, payload.NumBit, ret);
+else
+av_log(avctx, AV_LOG_DEBUG, "mfxPayload Type: %d  Numbits 
%d\n", payload.Type, payload.NumBit);
+}
+}
+
+if (out)
+return ff_h264_export_frame_props(avctx, , NULL, out);
+
+return 0;
+}
+
+static int parse_sei_hevc(AVCodecContext* avctx, QSVContext* q, QSVFrame* out)
+{
+HEVCSEI sei = { 0 };
+HEVCParamSets ps = { 0 };
+GetBitContext gb = { 0 };
+mfxPayload payload = { 0, .Data = >payload_buffer[0], .BufSize = 
sizeof(q->payload_buffer) };
+mfxFrameSurface1 *surface = >surface;
+mfxU64 ts;
+int ret, has_logged = 0;
+
+while (1) {
+int start;
+memset(payload.Data, 0, payload.BufSize);
+
+ret = MFXVideoDECODE_GetPayload(q->session, , );
+if (ret == MFX_ERR_NOT_ENOUGH_BUFFER) {
+av_log(avctx, AV_LOG_WARNING, "Warning: Insufficient buffer on 
GetPayload(). Size: %"PRIu64" Needed: %d\n", sizeof(q->payload_buffer), 
payload.BufSize);
+return 0;
+}
+if (ret != MFX_ERR_NONE)
+return ret;
+
+if (payload.NumBit == 0 || payload.NumBit >= payload.BufSize * 8)
+break;
+
+if (!has_logged) {
+has_logged = 1;
+av_log(avctx, AV_LOG_VERBOSE, 
"-\n");
+av_log(avctx, AV_LOG_VERBOSE, "Start reading SEI - payload 
timestamp: %llu - surface timestamp: %llu\n", ts, surface->Data.TimeStamp);
+}
+
+if (ts != surface->Data.TimeStamp) {
+av_log(avctx, AV_LOG_WARNING, "GetPayload timestamp (%llu) does 
not match surface timestamp: (%llu)\n", ts, surface->Data.TimeStamp);
+}
+
+start = fin

[FFmpeg-devel] [PATCH v4 5/6] avcodec/h264dec: make h264_export_frame_props() accessible

2022-06-26 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/h264_slice.c | 98 +
 libavcodec/h264dec.h|  2 +
 2 files changed, 52 insertions(+), 48 deletions(-)

diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index d56722a5c2..f2a4c1c657 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1157,11 +1157,10 @@ static int h264_init_ps(H264Context *h, const 
H264SliceContext *sl, int first_sl
 return 0;
 }
 
-static int h264_export_frame_props(H264Context *h)
+int ff_h264_export_frame_props(AVCodecContext *logctx, H264SEIContext *sei, 
H264Context *h, AVFrame *out)
 {
-const SPS *sps = h->ps.sps;
-H264Picture *cur = h->cur_pic_ptr;
-AVFrame *out = cur->f;
+const SPS *sps = h ? h->ps.sps : NULL;
+H264Picture *cur = h ? h->cur_pic_ptr : NULL;
 
 out->interlaced_frame = 0;
 out->repeat_pict  = 0;
@@ -1169,19 +1168,19 @@ static int h264_export_frame_props(H264Context *h)
 /* Signal interlacing information externally. */
 /* Prioritize picture timing SEI information over used
  * decoding process if it exists. */
-if (h->sei.picture_timing.present) {
-int ret = ff_h264_sei_process_picture_timing(>sei.picture_timing, 
sps,
- h->avctx);
+if (sps && sei->picture_timing.present) {
+int ret = ff_h264_sei_process_picture_timing(>picture_timing, sps,
+ logctx);
 if (ret < 0) {
-av_log(h->avctx, AV_LOG_ERROR, "Error processing a picture timing 
SEI\n");
-if (h->avctx->err_recognition & AV_EF_EXPLODE)
+av_log(logctx, AV_LOG_ERROR, "Error processing a picture timing 
SEI\n");
+if (logctx->err_recognition & AV_EF_EXPLODE)
 return ret;
-h->sei.picture_timing.present = 0;
+sei->picture_timing.present = 0;
 }
 }
 
-if (sps->pic_struct_present_flag && h->sei.picture_timing.present) {
-H264SEIPictureTiming *pt = >sei.picture_timing;
+if (h && sps && sps->pic_struct_present_flag && 
sei->picture_timing.present) {
+H264SEIPictureTiming *pt = >picture_timing;
 switch (pt->pic_struct) {
 case H264_SEI_PIC_STRUCT_FRAME:
 break;
@@ -1215,21 +1214,23 @@ static int h264_export_frame_props(H264Context *h)
 if ((pt->ct_type & 3) &&
 pt->pic_struct <= H264_SEI_PIC_STRUCT_BOTTOM_TOP)
 out->interlaced_frame = (pt->ct_type & (1 << 1)) != 0;
-} else {
+} else if (h) {
 /* Derive interlacing flag from used decoding process. */
 out->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h);
 }
-h->prev_interlaced_frame = out->interlaced_frame;
 
-if (cur->field_poc[0] != cur->field_poc[1]) {
+if (h)
+h->prev_interlaced_frame = out->interlaced_frame;
+
+if (sps && cur->field_poc[0] != cur->field_poc[1]) {
 /* Derive top_field_first from field pocs. */
 out->top_field_first = cur->field_poc[0] < cur->field_poc[1];
-} else {
-if (sps->pic_struct_present_flag && h->sei.picture_timing.present) {
+} else if (sps) {
+if (sps->pic_struct_present_flag && sei->picture_timing.present) {
 /* Use picture timing SEI information. Even if it is a
  * information of a past frame, better than nothing. */
-if (h->sei.picture_timing.pic_struct == 
H264_SEI_PIC_STRUCT_TOP_BOTTOM ||
-h->sei.picture_timing.pic_struct == 
H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP)
+if (sei->picture_timing.pic_struct == 
H264_SEI_PIC_STRUCT_TOP_BOTTOM ||
+sei->picture_timing.pic_struct == 
H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP)
 out->top_field_first = 1;
 else
 out->top_field_first = 0;
@@ -1243,11 +1244,11 @@ static int h264_export_frame_props(H264Context *h)
 }
 }
 
-if (h->sei.frame_packing.present &&
-h->sei.frame_packing.arrangement_type <= 6 &&
-h->sei.frame_packing.content_interpretation_type > 0 &&
-h->sei.frame_packing.content_interpretation_type < 3) {
-H264SEIFramePacking *fp = >sei.frame_packing;
+if (sei->frame_packing.present &&
+sei->frame_packing.arrangement_type <= 6 &&
+sei->frame_packing.content_interpretation_type > 0 &&
+sei->frame_packing.content_interpretation_type < 3) {
+H264SEIFramePacking *fp = >frame_packing;
 AVStereo3D *stereo = av_stereo3d_create_s

[FFmpeg-devel] [PATCH v4 4/6] avcodec/hevcdec: make set_side_data() accessible

2022-06-26 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/hevcdec.c | 117 +--
 libavcodec/hevcdec.h |   9 
 2 files changed, 67 insertions(+), 59 deletions(-)

diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index e84c30dd13..b4d8db8c6b 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -2726,23 +2726,22 @@ error:
 return res;
 }
 
-static int set_side_data(HEVCContext *s)
+int ff_hevc_set_side_data(AVCodecContext *logctx, HEVCSEI *sei, HEVCContext 
*s, AVFrame *out)
 {
-AVFrame *out = s->ref->frame;
-int ret;
+int ret = 0;
 
-if (s->sei.frame_packing.present &&
-s->sei.frame_packing.arrangement_type >= 3 &&
-s->sei.frame_packing.arrangement_type <= 5 &&
-s->sei.frame_packing.content_interpretation_type > 0 &&
-s->sei.frame_packing.content_interpretation_type < 3) {
+if (sei->frame_packing.present &&
+sei->frame_packing.arrangement_type >= 3 &&
+sei->frame_packing.arrangement_type <= 5 &&
+sei->frame_packing.content_interpretation_type > 0 &&
+sei->frame_packing.content_interpretation_type < 3) {
 AVStereo3D *stereo = av_stereo3d_create_side_data(out);
 if (!stereo)
 return AVERROR(ENOMEM);
 
-switch (s->sei.frame_packing.arrangement_type) {
+switch (sei->frame_packing.arrangement_type) {
 case 3:
-if (s->sei.frame_packing.quincunx_subsampling)
+if (sei->frame_packing.quincunx_subsampling)
 stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
 else
 stereo->type = AV_STEREO3D_SIDEBYSIDE;
@@ -2755,21 +2754,21 @@ static int set_side_data(HEVCContext *s)
 break;
 }
 
-if (s->sei.frame_packing.content_interpretation_type == 2)
+if (sei->frame_packing.content_interpretation_type == 2)
 stereo->flags = AV_STEREO3D_FLAG_INVERT;
 
-if (s->sei.frame_packing.arrangement_type == 5) {
-if (s->sei.frame_packing.current_frame_is_frame0_flag)
+if (sei->frame_packing.arrangement_type == 5) {
+if (sei->frame_packing.current_frame_is_frame0_flag)
 stereo->view = AV_STEREO3D_VIEW_LEFT;
 else
 stereo->view = AV_STEREO3D_VIEW_RIGHT;
 }
 }
 
-if (s->sei.display_orientation.present &&
-(s->sei.display_orientation.anticlockwise_rotation ||
- s->sei.display_orientation.hflip || 
s->sei.display_orientation.vflip)) {
-double angle = s->sei.display_orientation.anticlockwise_rotation * 360 
/ (double) (1 << 16);
+if (sei->display_orientation.present &&
+(sei->display_orientation.anticlockwise_rotation ||
+ sei->display_orientation.hflip || sei->display_orientation.vflip)) {
+double angle = sei->display_orientation.anticlockwise_rotation * 360 / 
(double) (1 << 16);
 AVFrameSideData *rotation = av_frame_new_side_data(out,

AV_FRAME_DATA_DISPLAYMATRIX,
sizeof(int32_t) * 
9);
@@ -2788,17 +2787,17 @@ static int set_side_data(HEVCContext *s)
* (1 - 2 * !!s->sei.display_orientation.vflip);
 av_display_rotation_set((int32_t *)rotation->data, angle);
 av_display_matrix_flip((int32_t *)rotation->data,
-   s->sei.display_orientation.hflip,
-   s->sei.display_orientation.vflip);
+   sei->display_orientation.hflip,
+   sei->display_orientation.vflip);
 }
 
 // Decrement the mastering display flag when IRAP frame has 
no_rasl_output_flag=1
 // so the side data persists for the entire coded video sequence.
-if (s->sei.mastering_display.present > 0 &&
+if (s && sei->mastering_display.present > 0 &&
 IS_IRAP(s) && s->no_rasl_output_flag) {
-s->sei.mastering_display.present--;
+sei->mastering_display.present--;
 }
-if (s->sei.mastering_display.present) {
+if (sei->mastering_display.present) {
 // HEVC uses a g,b,r ordering, which we convert to a more natural r,g,b
 const int mapping[3] = {2, 0, 1};
 const int chroma_den = 5;
@@ -2811,25 +2810,25 @@ static int set_side_data(HEVCContext *s)
 
 for (i = 0; i < 3; i++) {
 const int j = mapping[i];
-metadata->display_primaries[i][0].num = 
s->sei.mastering_display.display_primaries[j][0];
+metadata->display_primaries[i][0].num 

[FFmpeg-devel] [PATCH v6 25/25] avcodec/dvbsubdec: Fix conditions for fallback to default resolution

2022-06-26 Thread softworkz
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 8d44529b4a..06f39161a8 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -34,7 +34,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)
 
@@ -1450,8 +1450,12 @@ static int dvbsub_decode(AVCodecContext *avctx, 
AVSubtitle *sub,
 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");
 
@@ -1496,34 +1500,28 @@ static int dvbsub_decode(AVCodecContext *avctx, 
AVSubtitle *sub,
 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",
@@ -1536,13 +1534,24 @@ static int dvbsub_decode(AVCodecContext *avctx, 
AVSubtitle *sub,
 
 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 v6 23/25] avcodec/subtitles: Migrate subtitle encoders to frame-based API

2022-06-26 Thread softworkz
From: softworkz 

and provide a compatibility shim for the legacy api

Signed-off-by: softworkz 
---
 libavcodec/assenc.c | 189 ++--
 libavcodec/avcodec.h|   5 +-
 libavcodec/codec_internal.h |  12 ---
 libavcodec/dvbsubenc.c  |  96 ++
 libavcodec/dvdsubenc.c  | 102 +++
 libavcodec/encode.c |  61 +++-
 libavcodec/movtextenc.c | 114 --
 libavcodec/srtenc.c | 108 ++---
 libavcodec/tests/avcodec.c  |   5 +-
 libavcodec/ttmlenc.c| 101 ++-
 libavcodec/utils.c  |   1 -
 libavcodec/webvttenc.c  |  86 +++-
 libavcodec/xsubenc.c|  88 ++---
 13 files changed, 688 insertions(+), 280 deletions(-)

diff --git a/libavcodec/assenc.c b/libavcodec/assenc.c
index 391d690133..5067244e77 100644
--- a/libavcodec/assenc.c
+++ b/libavcodec/assenc.c
@@ -25,69 +25,194 @@
 
 #include "avcodec.h"
 #include "codec_internal.h"
+#include "encode.h"
 #include "libavutil/ass_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(_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(>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_l

[FFmpeg-devel] [PATCH v6 22/25] avfilter/snull, strim: Add snull and strim filters

2022-06-26 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 configure|  2 +-
 libavfilter/Makefile |  2 ++
 libavfilter/allfilters.c |  2 ++
 libavfilter/sf_snull.c   | 50 +
 libavfilter/trim.c   | 60 +++-
 5 files changed, 114 insertions(+), 2 deletions(-)
 create mode 100644 libavfilter/sf_snull.c

diff --git a/configure b/configure
index f74077b439..285bdf958e 100755
--- a/configure
+++ b/configure
@@ -3817,7 +3817,7 @@ avutil_extralibs="d3d11va_extralibs nanosleep_extralibs 
pthreads_extralibs vaapi
 # programs
 ffmpeg_deps="avcodec avfilter avformat"
 ffmpeg_select="aformat_filter anull_filter atrim_filter format_filter
-   hflip_filter null_filter
+   snull_filter strim_filter hflip_filter null_filter
transpose_filter trim_filter vflip_filter"
 ffmpeg_suggest="ole32 psapi shell32"
 ffplay_deps="avcodec avformat swscale swresample sdl2"
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index adbc16a5a9..697eee57d2 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -581,7 +581,9 @@ OBJS-$(CONFIG_NULLSINK_FILTER)   += 
vsink_nullsink.o
 # subtitle filters
 OBJS-$(CONFIG_CENSOR_FILTER) += sf_textmod.o
 OBJS-$(CONFIG_SHOW_SPEAKER_FILTER)   += sf_textmod.o
+OBJS-$(CONFIG_SNULL_FILTER)  += sf_snull.o
 OBJS-$(CONFIG_SPLITCC_FILTER)+= sf_splitcc.o
+OBJS-$(CONFIG_STRIM_FILTER)  += trim.o
 OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
 OBJS-$(CONFIG_SUBFEED_FILTER)+= sf_subfeed.o
 OBJS-$(CONFIG_SUBSCALE_FILTER)   += sf_subscale.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 82297e9657..fa7bee3bd8 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -573,7 +573,9 @@ extern const AVFilter ff_avsrc_movie;
 extern const AVFilter ff_sf_censor;
 extern const AVFilter ff_sf_graphicsub2text;
 extern const AVFilter ff_sf_showspeaker;
+extern const AVFilter ff_sf_snull;
 extern const AVFilter ff_sf_splitcc;
+extern const AVFilter ff_sf_strim;
 extern const AVFilter ff_sf_stripstyles;
 extern const AVFilter ff_sf_subfeed;
 extern const AVFilter ff_sf_subscale;
diff --git a/libavfilter/sf_snull.c b/libavfilter/sf_snull.c
new file mode 100644
index 00..064c8d5c3a
--- /dev/null
+++ b/libavfilter/sf_snull.c
@@ -0,0 +1,50 @@
+/*
+ * 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
+ * null subtitle filter
+ */
+
+#include "avfilter.h"
+#include "internal.h"
+#include "libavutil/internal.h"
+
+static const AVFilterPad avfilter_sf_snull_inputs[] = {
+{
+.name = "default",
+.type = AVMEDIA_TYPE_SUBTITLE,
+},
+};
+
+static const AVFilterPad avfilter_sf_snull_outputs[] = {
+{
+.name = "default",
+.type = AVMEDIA_TYPE_SUBTITLE,
+},
+};
+
+const AVFilter ff_sf_snull = {
+.name  = "snull",
+.description   = NULL_IF_CONFIG_SMALL("Pass the source unchanged to the 
output."),
+.flags = AVFILTER_FLAG_METADATA_ONLY,
+FILTER_INPUTS(avfilter_sf_snull_inputs),
+FILTER_OUTPUTS(avfilter_sf_snull_outputs),
+};
diff --git a/libavfilter/trim.c b/libavfilter/trim.c
index ee6e821cd2..a25366497b 100644
--- a/libavfilter/trim.c
+++ b/libavfilter/trim.c
@@ -83,7 +83,7 @@ static int config_input(AVFilterLink *inlink)
 {
 AVFilterContext *ctx = inlink->dst;
 TrimContext   *s = ctx->priv;
-AVRational tb = (inlink->type == AVMEDIA_TYPE_VIDEO) ?
+AVRational tb = (inlink->type != AVMEDIA_TYPE_AUDIO) ?
  inlink->time_base : (AVRational){ 1, inlink->sample_rate 
};
 
 if (s->start_time != INT64_MAX) {
@@ -369,3 +369,61 @@ const AVFilter ff_af_atrim = {
 FILTER_OUTPUTS(atrim_outputs),
 };
 #endif // CONFIG_ATRIM_FILTER
+
+#if CONFIG_STRIM_FILTER
+
+static int sconfig_output(AVFilterLink *outlink)
+{
+AVFilterContext *ctx = outlink->src;
+AVFilterLink *inlink = ctx->inputs[0];
+
+outlink->form

[FFmpeg-devel] [PATCH v6 21/25] avfilter/text2graphicsub: Added text2graphicsub subtitle filter

2022-06-26 Thread softworkz
From: softworkz 

Added a text2graphicsub subtitle filter which converts text-based
subtitle tracks to bitmap-based subtitle tracks. The filter uses libass
to render the subtitles.
It takes as parameters an output height and width, as well as a number
of colors in the output palette as well as sources of fonts. All its
arguments are optional.

Reviewed-by: softworkz 
Signed-off-by: softworkz 
Signed-off-by: tcoza 
---
 configure|   1 +
 doc/filters.texi |  51 +++
 libavfilter/Makefile |   1 +
 libavfilter/allfilters.c |   1 +
 libavfilter/sf_text2graphicsub.c | 634 +++
 5 files changed, 688 insertions(+)
 create mode 100644 libavfilter/sf_text2graphicsub.c

diff --git a/configure b/configure
index 89db322fb8..f74077b439 100755
--- a/configure
+++ b/configure
@@ -3734,6 +3734,7 @@ subscale_filter_deps="swscale avcodec"
 subtitles_filter_deps="avformat avcodec libass"
 super2xsai_filter_deps="gpl"
 pixfmts_super2xsai_test_deps="super2xsai_filter"
+text2graphicsub_filter_deps="avformat avcodec libass"
 textsub2video_filter_deps="avcodec libass"
 tinterlace_filter_deps="gpl"
 tinterlace_merge_test_deps="tinterlace_filter"
diff --git a/doc/filters.texi b/doc/filters.texi
index 00fa9bbac5..56da160634 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -27744,6 +27744,57 @@ ffmpeg -y -y -loglevel verbose -i 
"https://streams.videolan.org/samples/sub/larg
 @end example
 @end itemize
 
+@section text2graphicsub
+
+Converts a text-based subtitle track to a bitmap-based subtitle track.
+
+The text2graphicsub filter uses libass to render all the subtitle
+frames in a text-based subtitle track (such as srt or ass) to allow
+its encoding with a bitmap-based subtitle encoder (such as dvd_subtitle).
+
+Inputs:
+- 0: Subtitles [text]
+
+Outputs:
+- 0: Subtitles [bitmap]
+
+It accepts the following parameters:
+
+@table @option
+
+@item s, size
+Set the size of the output. Default from input track.
+
+@item n, num_colors
+Set the number of palette colors for output images,
+Range [2,256]. Default 16.
+
+@item f, filename
+Set the media container from which to extract fonts required
+for rendering the subtitles, usually the same as the input
+track's media container. Can be omitted.
+
+@item fd, fontsdir
+Set the directory from which to load fonts required for
+rendering the subtitles. Can be used with 'fonts'. Can be omitted.
+
+@item ss, stripstyles
+Remove certain styles from an ass track which do not render well.
+Stripped styles include blurs, fades, and other animations.
+Default yes.
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Convert a video's text-based subtitle track to a dvd_subtitle subtitle track.
+@example
+ffmpeg -i video.mkv -map 0:v -map 0:a -filter_complex 
[0:s]text2graphicsub=f=video.mkv[dvd_sub] -map [dvd_sub] -c copy -c:s 
dvd_subtitle output.mkv
+@end example
+@end itemize
+
 @c man end SUBTITLE FILTERS
 
 @chapter Multimedia Filters
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 780e5333a0..adbc16a5a9 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -585,6 +585,7 @@ OBJS-$(CONFIG_SPLITCC_FILTER)+= sf_splitcc.o
 OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
 OBJS-$(CONFIG_SUBFEED_FILTER)+= sf_subfeed.o
 OBJS-$(CONFIG_SUBSCALE_FILTER)   += sf_subscale.o
+OBJS-$(CONFIG_TEXT2GRAPHICSUB_FILTER)+= sf_text2graphicsub.o
 OBJS-$(CONFIG_TEXTMOD_FILTER)+= sf_textmod.o
 
 # multimedia filters
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index ff56661b67..82297e9657 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -577,6 +577,7 @@ extern const AVFilter ff_sf_splitcc;
 extern const AVFilter ff_sf_stripstyles;
 extern const AVFilter ff_sf_subfeed;
 extern const AVFilter ff_sf_subscale;
+extern const AVFilter ff_sf_text2graphicsub;
 extern const AVFilter ff_sf_textmod;
 
 /* those filters are part of public or internal API,
diff --git a/libavfilter/sf_text2graphicsub.c b/libavfilter/sf_text2graphicsub.c
new file mode 100644
index 00..1fd7a76c53
--- /dev/null
+++ b/libavfilter/sf_text2graphicsub.c
@@ -0,0 +1,634 @@
+/*
+ * Copyright (c) 2021 tcoza
+ *
+ * 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

[FFmpeg-devel] [PATCH v6 20/25] avfilter/subfeed: add subtitle feed filter

2022-06-26 Thread softworkz
From: softworkz 

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

diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 0f43937205..780e5333a0 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -583,6 +583,7 @@ OBJS-$(CONFIG_CENSOR_FILTER) += sf_textmod.o
 OBJS-$(CONFIG_SHOW_SPEAKER_FILTER)   += sf_textmod.o
 OBJS-$(CONFIG_SPLITCC_FILTER)+= sf_splitcc.o
 OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
+OBJS-$(CONFIG_SUBFEED_FILTER)+= sf_subfeed.o
 OBJS-$(CONFIG_SUBSCALE_FILTER)   += sf_subscale.o
 OBJS-$(CONFIG_TEXTMOD_FILTER)+= sf_textmod.o
 
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 6792665730..ff56661b67 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -575,6 +575,7 @@ extern const AVFilter ff_sf_graphicsub2text;
 extern const AVFilter ff_sf_showspeaker;
 extern const AVFilter ff_sf_splitcc;
 extern const AVFilter ff_sf_stripstyles;
+extern const AVFilter ff_sf_subfeed;
 extern const AVFilter ff_sf_subscale;
 extern const AVFilter ff_sf_textmod;
 
diff --git a/libavfilter/sf_subfeed.c b/libavfilter/sf_subfeed.c
new file mode 100644
index 00..3227861ac0
--- /dev/null
+++ b/libavfilter/sf_subfeed.c
@@ -0,0 +1,412 @@
+/*
+ * 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(>fifo, NULL);
+
+return 0;
+}
+
+static void uninit(AVFilterContext *ctx)
+{
+SubFeedContext *s = ctx->priv;
+ff_framequeue_free(>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, >outcfg.formats)) < 0)
+return ret;
+
+if ((ret = ff_formats_ref(formats, >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 = in

[FFmpeg-devel] [PATCH v6 19/25] avfilter/subscale: Add filter for scaling and/or re-arranging graphical subtitles

2022-06-26 Thread softworkz
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 462d473c5f..89db322fb8 100755
--- a/configure
+++ b/configure
@@ -3730,6 +3730,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 4bbec62c02..00fa9bbac5 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -27580,6 +27580,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 targe

[FFmpeg-devel] [PATCH v6 18/25] avfilter/graphicsub2text: Add new graphicsub2text filter (OCR)

2022-06-26 Thread softworkz
From: softworkz 

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

diff --git a/configure b/configure
index bde13f3e09..462d473c5f 100755
--- a/configure
+++ b/configure
@@ -3663,6 +3663,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 b4bbbace7f..4bbec62c02 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -27174,6 +27174,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 958da451ea..6e6485c99a 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -307,6 +307,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_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
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 3aa1e5ebc0..cbd93c4236 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -571,6 +571,7 @@ extern const AVFilter ff_avsrc_movie;
 
 /* subtitle filters */
 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..47c7030939
--- /dev/null
+++ b/libavfilter/sf_graphicsub2text.c
@@ -0,0 +1,1137 @@
+/*
+ * 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.
+ 

[FFmpeg-devel] [PATCH v6 17/25] avfilter/splitcc: Add splitcc filter for closed caption handling

2022-06-26 Thread softworkz
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 99b4d7c8d7..bde13f3e09 100755
--- a/configure
+++ b/configure
@@ -3728,6 +3728,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 1158df64d2..b4bbbace7f 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -27408,6 +27408,69 @@ ffmpeg -i INPUT -filter_complex 
"showspeaker=format=colon:style='@{\\c&\
 @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 a99a0f6583..958da451ea 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -580,6 +580,7 @@ OBJS-$(CONFIG_NULLSINK_FILTER)   += 
vsink_nullsink.o
 # subtitle filters
 OBJS-$(CONFIG_CENSOR_FILTER) += sf_textmod.o
 OBJS-$(CONFIG_SHOW_SPEAKER_FILTER)   += sf_textmod.o
+OBJS-$(CONFIG_SPLITCC_FILTER)+= sf_splitcc.o
 OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
 OBJS-$(CONFIG_TEXTMOD_FILTER)+= sf_textmod.o
 
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 7a958b51d4..3aa1e5ebc0 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -572,6 +572,7 @@ extern const AVFilter ff_avsrc_movie;
 /* subtitle filters */
 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;
 
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,
+ * b

[FFmpeg-devel] [PATCH v6 16/25] avfilter/stripstyles: Add stripstyles filter

2022-06-26 Thread softworkz
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 | 237 +++
 4 files changed, 276 insertions(+)
 create mode 100644 libavfilter/sf_stripstyles.c

diff --git a/doc/filters.texi b/doc/filters.texi
index 0d078e2573..1158df64d2 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -27058,6 +27058,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 6a68c44e1c..a99a0f6583 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -580,6 +580,7 @@ OBJS-$(CONFIG_NULLSINK_FILTER)   += 
vsink_nullsink.o
 # subtitle filters
 OBJS-$(CONFIG_CENSOR_FILTER) += sf_textmod.o
 OBJS-$(CONFIG_SHOW_SPEAKER_FILTER)   += sf_textmod.o
+OBJS-$(CONFIG_STRIPSTYLES_FILTER)+= sf_stripstyles.o
 OBJS-$(CONFIG_TEXTMOD_FILTER)+= sf_textmod.o
 
 # multimedia filters
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 2228e414db..7a958b51d4 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -572,6 +572,7 @@ extern const AVFilter ff_avsrc_movie;
 /* subtitle filters */
 extern const AVFilter ff_sf_censor;
 extern const AVFilter ff_sf_showspeaker;
+extern const AVFilter ff_sf_stripstyles;
 extern const AVFilter ff_sf_textmod;
 
 /* those filters are part of public or internal API,
diff --git a/libavfilter/sf_stripstyles.c b/libavfilter/sf_stripstyles.c
new file mode 100644
index 00..78dc6f3ef4
--- /dev/null
+++ b/libavfilter/sf_stripstyles.c
@@ -0,0 +1,237 @@
+/*
+ * 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_internal.h"
+#include "libavutil/ass_split_internal.h"
+#include "libavutil/bprint.h"
+
+typedef struct StripStylesContext {
+const AVClass *class;
+enum AVSubtitleType format;
+int remove_animated;
+enum ASSSplitComponents keep_flags;
+int select_layer;
+} StripStylesContext;
+
+typedef struct DialogContext {
+StripStylesContext* ss_ctx;
+AVBPrint buffer;
+int drawing_scale;
+int is_animated;
+int plain_text_length;
+} 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))
+s->plain_text_length += len;
+av_bprint_append_data(>buffer, text, len);
+}
+
+static void dialog_new_line_cb(void *priv, int forced)
+{

[FFmpeg-devel] [PATCH v6 14/25] avfilter/overlaytextsubs: Add overlaytextsubs and textsubs2video filters

2022-06-26 Thread softworkz
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 |   2 +
 libavfilter/vf_overlaytextsubs.c | 680 +++
 5 files changed, 799 insertions(+)
 create mode 100644 libavfilter/vf_overlaytextsubs.c

diff --git a/configure b/configure
index 0580e4a536..99b4d7c8d7 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"
@@ -3730,6 +3731,7 @@ stereo3d_filter_deps="gpl"
 subtitles_filter_deps="avformat avcodec libass"
 super2xsai_filter_deps="gpl"
 pixfmts_super2xsai_test_deps="super2xsai_filter"
+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 a77546de3d..b73a380515 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -27106,6 +27106,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 
overlaytextsubs 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 ",".

[FFmpeg-devel] [PATCH v6 15/25] avfilter/textmod: Add textmod, censor and show_speaker filters

2022-06-26 Thread softworkz
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 |   5 +
 libavfilter/sf_textmod.c | 710 +++
 4 files changed, 926 insertions(+)
 create mode 100644 libavfilter/sf_textmod.c

diff --git a/doc/filters.texi b/doc/filters.texi
index b73a380515..0d078e2573 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -26998,6 +26998,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
+R

[FFmpeg-devel] [PATCH v6 13/25] avfilter/overlaygraphicsubs: Add overlaygraphicsubs and graphicsub2video filters

2022-06-26 Thread softworkz
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 e525e87b3c..a77546de3d 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -26990,6 +26990,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 
'overlaygraphicsubs' 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 overlaygraphicsubs)
+@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 af52a77ebc..97ec9fc3b3 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -307,6 +307,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_GRAPHMONITO

[FFmpeg-devel] [PATCH v6 07/25] avcodec/subtitles: Replace deprecated enum values

2022-06-26 Thread softworkz
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 1a1363471d..7bb60c9b26 100644
--- a/libavcodec/assdec.c
+++ b/libavcodec/assdec.c
@@ -53,7 +53,7 @@ static int ass_decode_frame(AVCodecContext *avctx, AVSubtitle 
*sub,
 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 4d4007ffd9..8d44529b4a 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -796,7 +796,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 97f366cc74..cb6dbc 100644
--- a/libavcodec/dvdsubdec.c
+++ b/libavcodec/dvdsubdec.c
@@ -404,7 +404,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 d29db7d49c..24da94faee 100644
--- a/libavcodec/dvdsubenc.c
+++ b/libavcodec/dvdsubenc.c
@@ -269,7 +269,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 e50c6766c5..05399863b6 100644
--- a/libavcodec/pgssubdec.c
+++ b/libavcodec/pgssubdec.c
@@ -535,7 +535,7 @@ static int display_end_segment(AVCodecContext *avctx, 
AVSubtitle *sub,
 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, >objects);
diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c
index d62fa164a5..30c3595c97 100644
--- a/libavcodec/xsubdec.c
+++ b/libavcodec/xsubdec.c
@@ -107,7 +107,7 @@ static int decode_frame(AVCodecContext *avctx, AVSubtitle 
*sub,
 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 v6 08/25] fftools/play, probe: Adjust for subtitle changes

2022-06-26 Thread softworkz
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 040afa0189..111e157979 100644
--- a/fftools/ffplay.c
+++ b/fftools/ffplay.c
@@ -153,7 +153,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 */
@@ -574,7 +573,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 (;;) {
@@ -608,6 +607,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;
@@ -640,25 +642,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, _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);
 }
 }
 }
@@ -671,7 +659,6 @@ static void decoder_destroy(Decoder *d) {
 static void frame_queue_unref_item(Frame *vp)
 {
 av_frame_unref(vp->frame);
-avsubtitle_free(>sub);
 }
 
 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, 
int keep_last)
@@ -969,7 +956,7 @@ static void video_image_display(VideoState *is)
 if (frame_queue_nb_remaining(>subpq) > 0) {
 sp = frame_queue_peek(>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];
@@ -981,25 +968,27 @@ static void video_image_display(VideoState *is)
 if (realloc_texture(>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

[FFmpeg-devel] [PATCH v6 06/25] avcodec, avutil: Move ass helper functions to avutil as avpriv_ and extend ass dialog parsing

2022-06-26 Thread softworkz
From: softworkz 

Also add

- hard_space callback (for upcoming fix)
- extensible callback (for future extension)
- new API which allows tag filtering

Signed-off-by: softworkz 
---
 libavcodec/Makefile   |  56 +++---
 libavcodec/ass.h  | 151 +--
 libavcodec/ass_split.h| 191 ---
 libavcodec/assdec.c   |   2 +-
 libavcodec/assenc.c   |   2 +-
 libavcodec/ccaption_dec.c |  20 +-
 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   | 115 
 libavutil/ass_internal.h  | 135 ++
 {libavcodec => libavutil}/ass_split.c | 179 +++---
 libavutil/ass_split_internal.h| 254 ++
 27 files changed, 726 insertions(+), 492 deletions(-)
 delete mode 100644 libavcodec/ass_split.h
 rename {libavcodec => libavutil}/ass.c (59%)
 create mode 100644 libavutil/ass_internal.h
 rename {libavcodec => libavutil}/ass_split.c (71%)
 create mode 100644 libavutil/ass_split_internal.h

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 3b8f7b5e01..4bfc90b6e9 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -221,10 +221,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
@@ -265,7 +265,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
@@ -442,7 +442,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 \
@@ -464,7 +464,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
@@ -479,8 +479,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_ENCODER) += movtextenc.o ass_s

[FFmpeg-devel] [PATCH v6 11/25] avfilter/avfilter: Fix hardcoded input index

2022-06-26 Thread softworkz
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 853e2b967f..e6217b60d6 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -451,7 +451,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;
 
@@ -460,8 +460,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));
@@ -1161,6 +1161,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 (>dst->input_pads[i] == in->dstpad) {
+input_index = i;
+break;
+}
+}
 
 av_assert0(!in->status_out);
 if (!filter->nb_outputs) {
@@ -1170,7 +1178,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;
 }
@@ -1207,7 +1215,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 v6 12/25] avfilter/sbuffer: Add sbuffersrc and sbuffersink filters

2022-06-26 Thread softworkz
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 3a97610209..0580e4a536 100755
--- a/configure
+++ b/configure
@@ -7880,7 +7880,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 "_%s,\n" $c >> $TMPH
 done
 fi
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index ec70feef11..5288480a55 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -571,8 +571,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 e269cf72d1..204e9bad6c 100644
--- a/libavfilter/buffersink.c
+++ b/libavfilter/buffersink.c
@@ -30,6 +30,8 @@
 #include "libavutil/internal.h"
 #include "libavutil/opt.h"
 
+#include "libavcodec/avcodec.h"
+
 #define FF_INTERNAL_FIELDS 1
 #include "framequeue.h"
 
@@ -61,6 +63,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;
 
@@ -372,6 +378,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_format(, 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[] = {
@@ -395,9 +423,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[] = {
 {
@@ -436,3 +471,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= _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 01e7c747d8..42c164e670 100644
--- a/libavfilter/buffersink.h
+++ b/libavfilter/buffersink.h
@@ -128,6 +128,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;
+} AVSBufferSinkP

[FFmpeg-devel] [PATCH v6 05/25] avfilter/subtitles: Update vf_subtitles to use new decoding api

2022-06-26 Thread softworkz
From: softworkz 

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

diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c
index 82e140e986..0ae156ad07 100644
--- a/libavfilter/vf_subtitles.c
+++ b/libavfilter/vf_subtitles.c
@@ -36,14 +36,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;
@@ -304,8 +302,42 @@ 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 enum AVSubtitleType 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;
+}
+
 static av_cold int init_subtitles(AVFilterContext *ctx)
 {
 int j, ret, sid;
@@ -318,6 +350,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);
@@ -398,13 +431,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 = 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(_opts, "sub_charenc", ass->charenc, 0);
 
@@ -460,27 +497,31 @@ static av_cold int init_subtitles(AVFilterContext *ctx)
   dec_ctx->subtitle_header_size);
 while (av_read_frame(fmt, ) >= 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, , _subtitle, );
+ret = decode(dec_ctx, sub, _subtitle, );
 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();
-avsubtitle_free();
+av_frame_free();
 }
 
 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 v6 10/25] avfilter/avfilter: Handle subtitle frames

2022-06-26 Thread softworkz
From: softworkz 

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

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 28c5430c3e..853e2b967f 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -52,7 +52,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,
@@ -60,12 +61,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" : "");
@@ -348,6 +350,14 @@ int avfilter_config_links(AVFilterContext *filter)
 
 if (!link->time_base.num && !link->time_base.den)
 link->time_base = (AVRational) {1, link->sample_rate};
+
+break;
+
+case AVMEDIA_TYPE_SUBTITLE:
+if (!link->time_base.num && !link->time_base.den)
+link->time_base = inlink ? inlink->time_base : 
AV_TIME_BASE_Q;
+
+break;
 }
 
 if (link->src->nb_inputs && link->src->inputs[0]->hw_frames_ctx &&
@@ -1013,6 +1023,10 @@ int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
 av_assert1(frame->width   == link->w);
 av_assert1(frame->height   == link->h);
 }
+} else if (link->type == AVMEDIA_TYPE_SUBTITLE) {
+if (frame->format != link->format) {
+av_log(link->dst, AV_LOG_WARNING, "Subtitle format change from %d 
to %d\n", link->format, frame->format);
+}
 } else {
 if (frame->format != link->format) {
 av_log(link->dst, AV_LOG_ERROR, "Format change is not 
supported\n");
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 2e8197c9a6..c436f304bc 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_major.h"
@@ -349,6 +350,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.
  */
@@ -357,6 +364,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 b7dbfc063b..f37be0203b 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -309,6 +309,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");
 }
@@ -439,6 +441,9 @@ static int query_formats(AVFilterGraph *graph, void 
*log_ctx)
 if (!link)
 continue;
 
+if (link->type == AVMEDIA_TYPE_SUBTITLE)
+continue;

[FFmpeg-devel] [PATCH v6 09/25] avfilter/subtitles: Add subtitles.c for subtitle frame allocation

2022-06-26 Thread softworkz
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 7ba1c8a861..af52a77ebc 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -20,6 +20,7 @@ OBJS = allfilters.o   
  \
framequeue.o \
graphdump.o  \
graphparser.o\
+   subtitles.o  \
version.o\
video.o  \
 
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 965f5d0f63..28c5430c3e 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -42,6 +42,7 @@
 #include "formats.h"
 #include "framepool.h"
 #include "internal.h"
+#include "subtitles.h"
 
 static void tlog_ref(void *ctx, AVFrame *ref, int end)
 {
@@ -1452,6 +1453,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 0f8da367d0..6c8496879a 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -89,6 +89,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();
+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 000000..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 

[FFmpeg-devel] [PATCH v6 04/25] avcodec/libzvbi: set subtitle type

2022-06-26 Thread softworkz
From: softworkz 

Signed-off-by: softworkz 
---
 libavcodec/libzvbi-teletextdec.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavcodec/libzvbi-teletextdec.c b/libavcodec/libzvbi-teletextdec.c
index 92466cc11e..2aab10a548 100644
--- a/libavcodec/libzvbi-teletextdec.c
+++ b/libavcodec/libzvbi-teletextdec.c
@@ -751,10 +751,13 @@ static int teletext_init_decoder(AVCodecContext *avctx)
 
 switch (ctx->format_id) {
 case 0:
+avctx->subtitle_type = AV_SUBTITLE_FMT_BITMAP;
 return 0;
 case 1:
+avctx->subtitle_type = AV_SUBTITLE_FMT_ASS;
 return ff_ass_subtitle_header_default(avctx);
 case 2:
+avctx->subtitle_type = AV_SUBTITLE_FMT_ASS;
 return my_ass_subtitle_header(avctx);
 }
 return AVERROR_BUG;
-- 
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 v6 03/25] avcodec/subtitles: Introduce new frame-based subtitle decoding API

2022-06-26 Thread softworkz
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.c  |   8 ++
 libavcodec/avcodec.h  |  10 ++-
 libavcodec/decode.c   |  60 --
 libavcodec/internal.h |  16 
 libavcodec/utils.c| 184 ++
 5 files changed, 269 insertions(+), 9 deletions(-)

diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
index 5f6e71a39e..0a1d961fc6 100644
--- a/libavcodec/avcodec.c
+++ b/libavcodec/avcodec.c
@@ -358,6 +358,14 @@ FF_DISABLE_DEPRECATION_WARNINGS
 FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
+// Set the subtitle type from the codec descriptor in case the decoder 
hasn't done itself
+if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE && avctx->subtitle_type 
== AV_SUBTITLE_FMT_UNKNOWN) {
+if(avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB)
+avctx->subtitle_type = AV_SUBTITLE_FMT_BITMAP;
+if(avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB)
+ avctx->subtitle_type = AV_SUBTITLE_FMT_ASS;
+}
+
 #if FF_API_AVCTX_TIMEBASE
 if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
 avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, 
(AVRational){avctx->ticks_per_frame, 1}));
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 56d551f92d..de87b0406b 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1698,7 +1698,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())
@@ -2056,6 +2056,8 @@ typedef struct AVCodecContext {
  * The decoder can then override during decoding as needed.
  */
 AVChannelLayout ch_layout;
+
+enum AVSubtitleType subtitle_type;
 } AVCodecContext;
 
 /**
@@ -2432,7 +2434,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);
 
 /**
@@ -2525,7 +2530,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/decode.c b/libavcodec/decode.c
index 1893caa6a6..e8ca7b6da4 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -573,6 +573,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, , _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, );
+
+frame->width = avctx->width;
+frame->height = avctx->height;
+frame->pkt_dts = avpkt->dts;
+}
+
+avsubtitle_free();
+
+return ret;
+}
+
 int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const 
AVPacket *avpkt)
 {
 AVCodecInternal *avci = avctx->internal;
@@ -587,6 +620,13 @@ int attribute_align_arg avcodec_send_packet(AVCodecContext 
*avctx, const AVPacke
 if (avpkt &

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

2022-06-26 Thread softworkz
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  | 206 +
 libavutil/frame.h  |  85 ++-
 libavutil/subfmt.c |  45 ++
 libavutil/subfmt.h |  47 +++
 5 files changed, 363 insertions(+), 21 deletions(-)
 create mode 100644 libavutil/subfmt.c

diff --git a/libavutil/Makefile b/libavutil/Makefile
index edec708ff5..48f78c81e5 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -165,6 +165,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 4c16488c66..eadeabd926 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"
 
 #if FF_API_OLD_CHANNEL_LAYOUT
@@ -52,6 +53,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));
@@ -72,7 +76,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)
@@ -251,6 +260,23 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
 }
 
+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->format < 0)
@@ -258,23 +284,41 @@ int av_frame_get_buffer(AVFrame *frame, int align)
 
 FF_DISABLE_DEPRECATION_WARNINGS
 if (frame->width > 0 && frame->height > 0)
-return get_video_buffer(frame, align);
+frame->type = AVMEDIA_TYPE_VIDEO;
 else if (frame->nb_samples > 0 &&
  (av_channel_layout_check(>ch_layout)
 #if FF_API_OLD_CHANNEL_LAYOUT
   || frame->channel_layout || frame->channels > 0
 #endif
  ))
-return get_audio_buffer(frame, align);
+frame->type = AVMEDIA_TYPE_AUDIO;
 FF_ENABLE_DEPRECATION_WARNINGS
 
-return AVERROR(EINVAL);
+return av_frame_get_buffer2(frame, align);
+}
+
+int av_frame_get_buffer2(AVFrame *frame, int align)
+{
+if (frame->format < 0)
+return AVERROR(EINVAL);
+
+switch (frame->type) {
+case AVMEDIA_TYPE_VIDEO:
+return get_video_buffer(frame, align);
+case AVMEDIA_TYPE_AUDIO:
+return get_audio_buffer(frame, align);
+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->sampl

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

2022-06-26 Thread softworkz
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 4dae23d06e..56d551f92d 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"
@@ -2255,24 +2256,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 29c170214c..edec708ff5 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -77,6 +77,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 2e9e02dda8..f9f84801a3 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -114,6 +114,7 @@
 #define FF_API_XVMC (LIBAVUTIL_VERSION_MAJOR < 58)
 #define FF_API_OLD_CHANNEL_LAYOUT   (LIBAVUTIL_VERSION_MAJOR < 58)
 #define FF_API_AV_FOPEN_UTF8(LIBAVUTIL_VERSION_MAJOR < 58)
+#define FF_API_OLD_SUBTITLES(LIBAVUTIL_VERSION_MAJOR < 58)
 
 /**
  * @}
-- 
ffmpeg-codebot

___
ffmpeg-devel mailing list
ffmpeg

  1   2   3   >