77 #define OFFSET(x) offsetof(FrameRateContext, x)
78 #define V AV_OPT_FLAG_VIDEO_PARAM
79 #define F AV_OPT_FLAG_FILTERING_PARAM
80 #define FRAMERATE_FLAG_SCD 01
85 {
"interp_start",
"point to start linear interpolation",
OFFSET(interp_start),
AV_OPT_TYPE_INT, {.i64=15}, 0, 255,
V|
F },
86 {
"interp_end",
"point to end linear interpolation",
OFFSET(interp_end),
AV_OPT_TYPE_INT, {.i64=240}, 0, 255,
V|
F },
103 ff_dlog(ctx,
"next_source()\n");
106 ff_dlog(ctx,
"next_source() unlink %d\n", s->
last);
109 for (i = s->
last; i > s->
frst; i--) {
110 ff_dlog(ctx,
"next_source() copy %d to %d\n", i - 1, i);
113 ff_dlog(ctx,
"next_source() make %d null\n", s->
frst);
122 ff_dlog(ctx,
"get_scene_score()\n");
132 const int p1_linesize = crnt->
linesize[0];
133 const int p2_linesize = next->
linesize[0];
135 ff_dlog(ctx,
"get_scene_score() process\n");
137 for (sad = y = 0; y < crnt->
height; y += 8) {
138 for (x = 0; x < p1_linesize; x += 8) {
139 sad += s->
sad(p1 + y * p1_linesize + x,
141 p2 + y * p2_linesize + x,
148 ret = av_clipf(
FFMIN(mafd, diff), 0, 100.0);
151 ff_dlog(ctx,
"get_scene_score() result is:%f\n", ret);
159 int64_t work_next_pts;
160 AVFrame *copy_src1, *copy_src2, *work;
163 ff_dlog(ctx,
"process_work_frame()\n");
173 ff_dlog(ctx,
"process_work_frame() no current frame cached: move on to next frame, do not output a frame\n");
180 ff_dlog(ctx,
"process_work_frame() work crnt pts:%"PRId64
"\n", s->
pts);
181 ff_dlog(ctx,
"process_work_frame() work next pts:%"PRId64
"\n", work_next_pts);
183 ff_dlog(ctx,
"process_work_frame() srce prev pts:%"PRId64
" at dest time base:%u/%u\n",
186 ff_dlog(ctx,
"process_work_frame() srce crnt pts:%"PRId64
" at dest time base:%u/%u\n",
189 ff_dlog(ctx,
"process_work_frame() srce next pts:%"PRId64
" at dest time base:%u/%u\n",
196 ff_dlog(ctx,
"process_work_frame() work crnt pts >= srce next pts: SKIP FRAME, move on to next frame, do not output a frame\n");
204 ff_dlog(ctx,
"process_work_frame() interpolate:%d/256\n", interpolate);
207 ff_dlog(ctx,
"process_work_frame() source is:NEXT\n");
210 if (s->
srce[s->
prev] && interpolate < -s->interp_end) {
211 ff_dlog(ctx,
"process_work_frame() source is:PREV\n");
216 if ((interpolate >= s->
interp_start && interpolate <= s->interp_end) || (interpolate <= -s->interp_start && interpolate >= -s->
interp_end)) {
217 double interpolate_scene_score = 0;
219 if (interpolate > 0) {
220 ff_dlog(ctx,
"process_work_frame() interpolate source is:NEXT\n");
223 ff_dlog(ctx,
"process_work_frame() interpolate source is:PREV\n");
228 ff_dlog(ctx,
"process_work_frame() interpolate scene score:%f\n", interpolate_scene_score);
231 if (interpolate_scene_score < s->scene_score && copy_src2) {
232 uint16_t src2_factor = abs(interpolate);
233 uint16_t src1_factor = 256 - src2_factor;
243 ff_dlog(ctx,
"process_work_frame() INTERPOLATE to create work frame\n");
244 for (plane = 0; plane < 4 && copy_src1->
data[
plane] && copy_src2->
data[
plane]; plane++) {
250 int cpy_src_h = (plane > 0 && plane < 3) ? (copy_src1->
height >> s->
vsub) : (copy_src1->
height);
253 if (plane <1 || plane >2) {
255 for (line = 0; line < cpy_src_h; line++) {
256 for (pixel = 0; pixel < cpy_line_width; pixel++) {
260 cpy_dst_data[
pixel] = ((cpy_src1_data[
pixel] * src1_factor) + (cpy_src2_data[pixel] * src2_factor) + 128) >> 8;
262 cpy_src1_data += cpy_src1_line_size;
263 cpy_src2_data += cpy_src2_line_size;
264 cpy_dst_data += cpy_dst_line_size;
268 for (line = 0; line < cpy_src_h; line++) {
269 for (pixel = 0; pixel < cpy_line_width; pixel++) {
273 cpy_dst_data[
pixel] = (((cpy_src1_data[
pixel] - 128) * src1_factor) + ((cpy_src2_data[
pixel] - 128) * src2_factor) + 32896) >> 8;
275 cpy_src1_data += cpy_src1_line_size;
276 cpy_src2_data += cpy_src2_line_size;
277 cpy_dst_data += cpy_dst_line_size;
284 ff_dlog(ctx,
"process_work_frame() CUT - DON'T INTERPOLATE\n");
288 ff_dlog(ctx,
"process_work_frame() COPY to the work frame\n");
299 ff_dlog(ctx,
"process_work_frame() REPEAT FRAME\n");
301 ff_dlog(ctx,
"process_work_frame() CONSUME FRAME, move to next frame\n");
305 ff_dlog(ctx,
"process_work_frame() output a frame\n");
318 ff_dlog(ctx,
"set_srce_frame_output_pts()\n");
332 int64_t
pts, average_srce_pts_delta = 0;
334 ff_dlog(ctx,
"set_work_frame_pts()\n");
339 ff_dlog(ctx,
"set_work_frame_pts() srce crnt pts:%"PRId64
"\n", s->
srce[s->
crnt]->
pts);
340 ff_dlog(ctx,
"set_work_frame_pts() srce next pts:%"PRId64
"\n", s->
srce[s->
next]->
pts);
342 ff_dlog(ctx,
"set_work_frame_pts() srce prev pts:%"PRId64
"\n", s->
srce[s->
prev]->
pts);
345 ff_dlog(ctx,
"set_work_frame_pts() initial average srce pts:%"PRId64
"\n", average_srce_pts_delta);
349 average_srce_pts_delta = average_srce_pts_delta?((average_srce_pts_delta+
pts)>>1):
pts;
351 average_srce_pts_delta = average_srce_pts_delta?((average_srce_pts_delta+
pts)>>1):
pts;
355 ff_dlog(ctx,
"set_work_frame_pts() average srce pts:%"PRId64
"\n", average_srce_pts_delta);
356 ff_dlog(ctx,
"set_work_frame_pts() average srce pts:%"PRId64
" at dest time base:%u/%u\n",
368 ff_dlog(ctx,
"set_frame_pts() average output pts from input timebase\n");
378 ff_dlog(ctx,
"set_work_frame_pts() calculated pts:%"PRId64
" at dest time base:%u/%u\n",
402 for (i = s->
frst + 1; i > s->
last; i++) {
434 for (plane = 0; plane < 4; plane++) {
481 ff_dlog(ctx,
"config_output()\n");
484 "config_output() input time base:%u/%u (%f)\n",
496 "time base:%u/%u -> %u/%u exact:%d\n",
508 "config_output() output time base:%u/%u (%f) w:%d h:%d\n",
511 outlink->
w, outlink->
h);
514 av_log(ctx,
AV_LOG_INFO,
"fps -> fps:%u/%u scene score:%f interpolate start:%d end:%d\n",
527 ff_dlog(ctx,
"request_frame()\n");
531 ff_dlog(ctx,
"request_frame() call source's request_frame()\n");
533 ff_dlog(ctx,
"request_frame() source's request_frame() returned error:%d\n", val);
536 ff_dlog(ctx,
"request_frame() source's request_frame() returned:%d\n", val);
540 ff_dlog(ctx,
"request_frame() REPEAT or FLUSH\n");
543 ff_dlog(ctx,
"request_frame() nothing else to do, return:EOF\n");
548 ff_dlog(ctx,
"request_frame() FLUSH\n");
551 for (i = s->
last; i > s->
frst; i--) {
552 if (!s->
srce[i - 1] && s->
srce[i]) {
553 ff_dlog(ctx,
"request_frame() copy:%d to:%d\n", i, i - 1);
584 .description =
NULL_IF_CONFIG_SMALL(
"Upsamples or downsamples progressive source between specified frame rates."),
586 .priv_class = &framerate_class,
590 .
inputs = framerate_inputs,
const char const char void * val
int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane)
Compute the size of an image line with format pix_fmt and width width for the plane plane...
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
This structure describes decoded (raw) audio or video data.
static av_cold void uninit(AVFilterContext *ctx)
double scene_score
score that denotes a scene change has happened
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
#define AV_LOG_WARNING
Something somehow does not look correct.
static const AVFilterPad outputs[]
Main libavfilter public API header.
int h
agreed upon image height
static double get_scene_score(AVFilterContext *ctx, AVFrame *crnt, AVFrame *next)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
AVFILTER_DEFINE_CLASS(framerate)
int interp_end
end of range to apply linear interpolation
const char * name
Pad name.
AVFilterLink ** inputs
array of pointers to input links
#define av_assert0(cond)
assert() equivalent, that is always enabled.
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
AVFrame * srce[N_SRCE]
buffered source frames
AVRational dest_frame_rate
output frames per second
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
static void interpolate(float *out, float v1, float v2, int size)
static double av_q2d(AVRational a)
Convert rational to double.
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range...
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
static int request_frame(AVFilterLink *outlink)
#define AVERROR_EOF
End of file.
static void set_srce_frame_dest_pts(AVFilterContext *ctx)
int interlaced_frame
The content of the picture is interlaced.
int flags
flags affecting frame rate conversion algorithm
int line_size[4]
bytes of pixel data per line for each plane
A filter pad used for either input or output.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
A link between two filters.
int width
width and height of the video frame
unsigned flags
Link processing flags.
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown; if left to 0/0, will be automatically be cop...
int interp_start
start of range to apply linear interpolation
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void * priv
private data for use by the filter
int(* av_pixelutils_sad_fn)(const uint8_t *src1, ptrdiff_t stride1, const uint8_t *src2, ptrdiff_t stride2)
Sum of abs(src1[x] - src2[x])
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link...
simple assert() macros that are a bit more flexible than ISO C assert().
#define FRAMERATE_FLAG_SCD
int64_t av_gcd(int64_t a, int64_t b)
Return the greatest common divisor of a and b.
static void next_source(AVFilterContext *ctx)
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
int w
agreed upon image width
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
common internal API header
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
double prev_mafd
previous MAFD (scene detect only)
int64_t average_srce_pts_dest_delta
average input pts delta converted from input rate to output rate
AVFilterContext * src
source filter
AVRational srce_time_base
timebase of source
Frame requests may need to loop in order to be fulfilled.
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
int format
agreed upon media format
int64_t srce_pts_dest[N_SRCE]
pts for source frames scaled to output timebase
#define AV_LOG_INFO
Standard information.
static const AVFilterPad framerate_outputs[]
static int query_formats(AVFilterContext *ctx)
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
int pending_srce_frames
how many input frames are still waiting to be processed
int64_t last_dest_frame_pts
pts of the last frame output
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
av_pixelutils_sad_fn av_pixelutils_get_sad_fn(int w_bits, int h_bits, int aligned, void *log_ctx)
Get a potentially optimized pointer to a Sum-of-absolute-differences function (see the av_pixelutils_...
Describe the class of an AVClass context structure.
int pending_end_frame
flag indicating we are waiting to call filter_frame()
static const AVFilterPad inputs[]
rational number numerator/denominator
AVRational dest_time_base
timebase of destination
offset must point to AVRational
const char * name
Filter name.
static av_cold int init(AVFilterContext *ctx)
AVFilterLink ** outputs
array of pointers to output links
static enum AVPixelFormat pix_fmts[]
static int64_t pts
Global timestamp for the audio frames.
static int process_work_frame(AVFilterContext *ctx, int stop)
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static void set_work_frame_pts(AVFilterContext *ctx)
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
av_pixelutils_sad_fn sad
Sum of the absolute difference function (scene detect only)
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
static av_always_inline int diff(const uint32_t a, const uint32_t b)
static const AVOption framerate_options[]
AVFilterContext * dst
dest filter
static int config_input(AVFilterLink *inlink)
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
static const AVFilterPad framerate_inputs[]
int flush
are we flushing final frames
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
static int config_output(AVFilterLink *outlink)
int64_t average_dest_pts_delta
calculated average output pts delta
int64_t pts
pts of frame we are working on
AVPixelFormat
Pixel format.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.