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@ltnglobal.com>
Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
This commit is contained in:
Devin Heitmueller 2023-05-05 15:09:04 -04:00 committed by Limin Wang
parent 61a9f3c0ce
commit cecf35ae3e
5 changed files with 32 additions and 0 deletions

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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

View File

@ -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;