mirror of https://git.ffmpeg.org/ffmpeg.git
avfilter/vf_fps: properly preserve CEA-708 captions
The existing implementation made an attempt to remove duplicate captions if increasing the framerate, but made no attempt to handle reducing the framerate, nor did it rewrite the caption payloads to have the appropriate cc_count (e.g. the cc_count needs to change from 20 to 10 when going from 1080i59 to 720p59 and vice-versa). Make use of the new ccfifo mechanism to ensure that caption data is properly preserved. Signed-off-by: Devin Heitmueller <dheitmueller@ltnglobal.com> Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
This commit is contained in:
parent
2b0e794ffc
commit
61a9f3c0ce
|
@ -34,6 +34,7 @@
|
||||||
#include "libavutil/mathematics.h"
|
#include "libavutil/mathematics.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
#include "avfilter.h"
|
#include "avfilter.h"
|
||||||
|
#include "ccfifo.h"
|
||||||
#include "filters.h"
|
#include "filters.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
@ -85,6 +86,7 @@ typedef struct FPSContext {
|
||||||
|
|
||||||
AVFrame *frames[2]; ///< buffered frames
|
AVFrame *frames[2]; ///< buffered frames
|
||||||
int frames_count; ///< number of buffered frames
|
int frames_count; ///< number of buffered frames
|
||||||
|
AVCCFifo *cc_fifo; ///< closed captions
|
||||||
|
|
||||||
int64_t next_pts; ///< pts of the next frame to output
|
int64_t next_pts; ///< pts of the next frame to output
|
||||||
|
|
||||||
|
@ -165,6 +167,7 @@ static av_cold void uninit(AVFilterContext *ctx)
|
||||||
frame = shift_frame(ctx, s);
|
frame = shift_frame(ctx, s);
|
||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
}
|
}
|
||||||
|
ff_ccfifo_freep(&s->cc_fifo);
|
||||||
|
|
||||||
av_log(ctx, AV_LOG_VERBOSE, "%d frames in, %d frames out; %d frames dropped, "
|
av_log(ctx, AV_LOG_VERBOSE, "%d frames in, %d frames out; %d frames dropped, "
|
||||||
"%d frames duplicated.\n", s->frames_in, s->frames_out, s->drop, s->dup);
|
"%d frames duplicated.\n", s->frames_in, s->frames_out, s->drop, s->dup);
|
||||||
|
@ -210,6 +213,11 @@ static int config_props(AVFilterLink* outlink)
|
||||||
s->in_pts_off, s->out_pts_off, s->start_time);
|
s->in_pts_off, s->out_pts_off, s->start_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
av_log(ctx, AV_LOG_VERBOSE, "fps=%d/%d\n", outlink->frame_rate.num, outlink->frame_rate.den);
|
av_log(ctx, AV_LOG_VERBOSE, "fps=%d/%d\n", outlink->frame_rate.num, outlink->frame_rate.den);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -242,6 +250,7 @@ static int read_frame(AVFilterContext *ctx, FPSContext *s, AVFilterLink *inlink,
|
||||||
av_log(ctx, AV_LOG_DEBUG, "Read frame with in pts %"PRId64", out pts %"PRId64"\n",
|
av_log(ctx, AV_LOG_DEBUG, "Read frame with in pts %"PRId64", out pts %"PRId64"\n",
|
||||||
in_pts, frame->pts);
|
in_pts, frame->pts);
|
||||||
|
|
||||||
|
ff_ccfifo_extract(s->cc_fifo, frame);
|
||||||
s->frames[s->frames_count++] = frame;
|
s->frames[s->frames_count++] = frame;
|
||||||
s->frames_in++;
|
s->frames_in++;
|
||||||
|
|
||||||
|
@ -289,7 +298,7 @@ static int write_frame(AVFilterContext *ctx, FPSContext *s, AVFilterLink *outlin
|
||||||
if (!frame)
|
if (!frame)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
// Make sure Closed Captions will not be duplicated
|
// Make sure Closed Captions will not be duplicated
|
||||||
av_frame_remove_side_data(s->frames[0], AV_FRAME_DATA_A53_CC);
|
ff_ccfifo_inject(s->cc_fifo, frame);
|
||||||
frame->pts = s->next_pts++;
|
frame->pts = s->next_pts++;
|
||||||
frame->duration = 1;
|
frame->duration = 1;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue