Skip to content

Commit f304c3a

Browse files
dheitmuellerlance-lmwang
authored andcommitted
avfilter/tinterlace: Properly preserve CEA-708 closed captions
Because the interlacing filter halves the effective framerate, we need to ensure that no CEA-708 data is lost as frames are merged. Make use of the new ccfifo mechanism to ensure that caption data is properly preserved as frames pass through the filter. Thanks to Thomas Mundt for review and noticing a couple of missed codepaths for injection on output. Thanks to Lance Wang for pointing out a memory leak. Signed-off-by: Devin Heitmueller <[email protected]> Signed-off-by: Limin Wang <[email protected]>
1 parent cecf35a commit f304c3a

File tree

2 files changed

+13
-0
lines changed

2 files changed

+13
-0
lines changed

libavfilter/tinterlace.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "libavutil/pixdesc.h"
3333
#include "drawutils.h"
3434
#include "avfilter.h"
35+
#include "ccfifo.h"
3536

3637
#define TINTERLACE_FLAG_VLPF 01
3738
#define TINTERLACE_FLAG_CVLPF 2
@@ -77,6 +78,7 @@ typedef struct TInterlaceContext {
7778
const AVPixFmtDescriptor *csp;
7879
void (*lowpass_line)(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp,
7980
ptrdiff_t mref, ptrdiff_t pref, int clip_max);
81+
AVCCFifo *cc_fifo;
8082
} TInterlaceContext;
8183

8284
void ff_tinterlace_init_x86(TInterlaceContext *interlace);

libavfilter/vf_tinterlace.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ static av_cold void uninit(AVFilterContext *ctx)
203203
av_frame_free(&tinterlace->next);
204204
av_freep(&tinterlace->black_data[0][0]);
205205
av_freep(&tinterlace->black_data[1][0]);
206+
ff_ccfifo_freep(&tinterlace->cc_fifo);
206207
}
207208

208209
static int config_out_props(AVFilterLink *outlink)
@@ -291,6 +292,11 @@ static int config_out_props(AVFilterLink *outlink)
291292
#endif
292293
}
293294

295+
if (!(tinterlace->cc_fifo = ff_ccfifo_alloc(outlink->frame_rate, ctx))) {
296+
av_log(ctx, AV_LOG_ERROR, "Failure to setup CC FIFO queue\n");
297+
return AVERROR(ENOMEM);
298+
}
299+
294300
av_log(ctx, AV_LOG_VERBOSE, "mode:%d filter:%s h:%d -> h:%d\n", tinterlace->mode,
295301
(tinterlace->flags & TINTERLACE_FLAG_CVLPF) ? "complex" :
296302
(tinterlace->flags & TINTERLACE_FLAG_VLPF) ? "linear" : "off",
@@ -375,6 +381,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
375381
tinterlace->cur = tinterlace->next;
376382
tinterlace->next = picref;
377383

384+
ff_ccfifo_extract(tinterlace->cc_fifo, picref);
385+
378386
cur = tinterlace->cur;
379387
next = tinterlace->next;
380388
/* we need at least two frames */
@@ -456,6 +464,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
456464
if (!out)
457465
return AVERROR(ENOMEM);
458466
out->pts /= 2; // adjust pts to new framerate
467+
ff_ccfifo_inject(tinterlace->cc_fifo, out);
459468
ret = ff_filter_frame(outlink, out);
460469
return ret;
461470
}
@@ -505,6 +514,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
505514
out->pts = cur->pts*2;
506515

507516
out->pts = av_rescale_q(out->pts, tinterlace->preout_time_base, outlink->time_base);
517+
ff_ccfifo_inject(tinterlace->cc_fifo, out);
508518
if ((ret = ff_filter_frame(outlink, out)) < 0)
509519
return ret;
510520

@@ -549,6 +559,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
549559

550560
out->pts = av_rescale_q(out->pts, tinterlace->preout_time_base, outlink->time_base);
551561
out->duration = av_rescale_q(1, av_inv_q(outlink->frame_rate), outlink->time_base);
562+
ff_ccfifo_inject(tinterlace->cc_fifo, out);
552563
ret = ff_filter_frame(outlink, out);
553564

554565
return ret;

0 commit comments

Comments
 (0)