[FFmpeg-cvslog] avfilter/yadif: Properly preserve CEA-708 closed captions

Devin Heitmueller git at videolan.org
Thu May 11 17:12:43 EEST 2023


ffmpeg | branch: master | Devin Heitmueller <devin.heitmueller at ltnglobal.com> | Fri May  5 15:09:04 2023 -0400| [cecf35ae3e997dd884295d692aa6829462394132] | committer: Limin Wang

avfilter/yadif: Properly preserve CEA-708 closed captions

Various deinterlacing modes have the effect of doubling the
framerate, and we need to ensure that the caption data isn't
duplicated (or else you get double captions on-screen).

Use the new ccfifo mechanism for yadif (and yadif_cuda and bwdif
since they use the same yadif core) so that CEA-708 data is
properly preserved through this filter.

Signed-off-by: Devin Heitmueller <dheitmueller at ltnglobal.com>
Signed-off-by: Limin Wang <lance.lmwang at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=cecf35ae3e997dd884295d692aa6829462394132
---

 libavfilter/vf_bwdif.c      | 8 ++++++++
 libavfilter/vf_yadif.c      | 8 ++++++++
 libavfilter/vf_yadif_cuda.c | 9 +++++++++
 libavfilter/yadif.h         | 2 ++
 libavfilter/yadif_common.c  | 5 +++++
 5 files changed, 32 insertions(+)

diff --git a/libavfilter/vf_bwdif.c b/libavfilter/vf_bwdif.c
index 34e8c5e234..51e1e02503 100644
--- a/libavfilter/vf_bwdif.c
+++ b/libavfilter/vf_bwdif.c
@@ -297,6 +297,7 @@ static av_cold void uninit(AVFilterContext *ctx)
     av_frame_free(&yadif->prev);
     av_frame_free(&yadif->cur );
     av_frame_free(&yadif->next);
+    ff_ccfifo_freep(&yadif->cc_fifo);
 }
 
 static const enum AVPixelFormat pix_fmts[] = {
@@ -332,6 +333,13 @@ static int config_props(AVFilterLink *link)
 
     if(yadif->mode&1)
         link->frame_rate = av_mul_q(link->src->inputs[0]->frame_rate, (AVRational){2,1});
+    else
+        link->frame_rate = ctx->inputs[0]->frame_rate;
+
+    if (!(yadif->cc_fifo = ff_ccfifo_alloc(link->frame_rate, ctx))) {
+        av_log(ctx, AV_LOG_ERROR, "Failure to setup CC FIFO queue\n");
+        return AVERROR(ENOMEM);
+    }
 
     if (link->w < 3 || link->h < 4) {
         av_log(ctx, AV_LOG_ERROR, "Video of less than 3 columns or 4 lines is not supported\n");
diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c
index 1be02de1a9..f77f8113ca 100644
--- a/libavfilter/vf_yadif.c
+++ b/libavfilter/vf_yadif.c
@@ -261,6 +261,7 @@ static av_cold void uninit(AVFilterContext *ctx)
     av_frame_free(&yadif->prev);
     av_frame_free(&yadif->cur );
     av_frame_free(&yadif->next);
+    ff_ccfifo_freep(&yadif->cc_fifo);
 }
 
 static const enum AVPixelFormat pix_fmts[] = {
@@ -293,6 +294,13 @@ static int config_output(AVFilterLink *outlink)
     if(s->mode & 1)
         outlink->frame_rate = av_mul_q(ctx->inputs[0]->frame_rate,
                                     (AVRational){2, 1});
+    else
+        outlink->frame_rate = ctx->inputs[0]->frame_rate;
+
+    if (!(s->cc_fifo = ff_ccfifo_alloc(outlink->frame_rate, ctx))) {
+        av_log(ctx, AV_LOG_ERROR, "Failure to setup CC FIFO queue\n");
+        return AVERROR(ENOMEM);
+    }
 
     if (outlink->w < 3 || outlink->h < 3) {
         av_log(ctx, AV_LOG_ERROR, "Video of less than 3 columns or lines is not supported\n");
diff --git a/libavfilter/vf_yadif_cuda.c b/libavfilter/vf_yadif_cuda.c
index 685b8a2035..f3f0b56768 100644
--- a/libavfilter/vf_yadif_cuda.c
+++ b/libavfilter/vf_yadif_cuda.c
@@ -205,6 +205,7 @@ static av_cold void deint_cuda_uninit(AVFilterContext *ctx)
     av_frame_free(&y->prev);
     av_frame_free(&y->cur);
     av_frame_free(&y->next);
+    ff_cc_fifo_freep(&y->cc_fifo);
 
     av_buffer_unref(&s->device_ref);
     s->hwctx = NULL;
@@ -291,6 +292,14 @@ static int config_output(AVFilterLink *link)
     if(y->mode & 1)
         link->frame_rate = av_mul_q(ctx->inputs[0]->frame_rate,
                                     (AVRational){2, 1});
+    else
+        link->frame_rate = ctx->inputs[0]->frame_rate;
+
+    if (!(s->cc_fifo = ff_cc_fifo_alloc(link->frame_rate, ctx))) {
+        av_log(ctx, AV_LOG_ERROR, "Failure to setup CC FIFO queue\n");
+        ret = AVERROR(ENOMEM);
+        goto exit;
+    }
 
     if (link->w < 3 || link->h < 3) {
         av_log(ctx, AV_LOG_ERROR, "Video of less than 3 columns or lines is not supported\n");
diff --git a/libavfilter/yadif.h b/libavfilter/yadif.h
index c928911b35..10775767e9 100644
--- a/libavfilter/yadif.h
+++ b/libavfilter/yadif.h
@@ -22,6 +22,7 @@
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
+#include "ccfifo.h"
 
 enum YADIFMode {
     YADIF_MODE_SEND_FRAME           = 0, ///< send 1 frame for each frame
@@ -76,6 +77,7 @@ typedef struct YADIFContext {
     int eof;
     uint8_t *temp_line;
     int temp_line_size;
+    AVCCFifo *cc_fifo;
 
     /*
      * An algorithm that treats first and/or last fields in a sequence
diff --git a/libavfilter/yadif_common.c b/libavfilter/yadif_common.c
index 2bd6111140..49ea7cfce4 100644
--- a/libavfilter/yadif_common.c
+++ b/libavfilter/yadif_common.c
@@ -65,6 +65,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
             yadif->out->pts = AV_NOPTS_VALUE;
         }
     }
+
+    ff_ccfifo_inject(yadif->cc_fifo, yadif->out);
     ret = ff_filter_frame(ctx->outputs[0], yadif->out);
 
     yadif->frame_pending = (yadif->mode&1) && !is_second;
@@ -101,6 +103,8 @@ int ff_yadif_filter_frame(AVFilterLink *link, AVFrame *frame)
 
     av_assert0(frame);
 
+    ff_ccfifo_extract(yadif->cc_fifo, frame);
+
     if (yadif->frame_pending)
         return_frame(ctx, 1);
 
@@ -142,6 +146,7 @@ int ff_yadif_filter_frame(AVFilterLink *link, AVFrame *frame)
         if (!yadif->out)
             return AVERROR(ENOMEM);
 
+        ff_ccfifo_inject(yadif->cc_fifo, yadif->out);
         av_frame_free(&yadif->prev);
         if (yadif->out->pts != AV_NOPTS_VALUE)
             yadif->out->pts *= 2;



More information about the ffmpeg-cvslog mailing list