FFmpeg
Loading...
Searching...
No Matches
vf_separatefields.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2013 Paul B Mahol
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include "libavutil/pixdesc.h"
22#include "avfilter.h"
23#include "filters.h"
24#include "video.h"
25
30
32{
33 AVFilterContext *ctx = outlink->src;
35 AVFilterLink *inlink = ctx->inputs[0];
36 FilterLink *il = ff_filter_link(inlink);
37 FilterLink *ol = ff_filter_link(outlink);
38
39 s->nb_planes = av_pix_fmt_count_planes(inlink->format);
40
41 if (inlink->h & 1) {
42 av_log(ctx, AV_LOG_ERROR, "height must be even\n");
44 }
45
46 outlink->time_base.num = inlink->time_base.num;
47 outlink->time_base.den = inlink->time_base.den * 2;
48 ol->frame_rate.num = il->frame_rate.num * 2;
49 ol->frame_rate.den = il->frame_rate.den;
50 outlink->w = inlink->w;
51 outlink->h = inlink->h / 2;
52
53 return 0;
54}
55
56static void extract_field(AVFrame *frame, int nb_planes, int type)
57{
58 int i;
59
60 for (i = 0; i < nb_planes; i++) {
61 if (type)
62 frame->data[i] = frame->data[i] + frame->linesize[i];
63 frame->linesize[i] *= 2;
64 }
65}
66
67static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
68{
69 AVFilterContext *ctx = inlink->dst;
71 AVFilterLink *outlink = ctx->outputs[0];
72 int ret;
73
74 inpicref->height = outlink->h;
76
77 if (!s->second) {
78 goto clone;
79 } else {
80 AVFrame *second = s->second;
81
82 extract_field(second, s->nb_planes, !!(second->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST));
83
84 if (second->pts != AV_NOPTS_VALUE &&
85 inpicref->pts != AV_NOPTS_VALUE)
86 second->pts += inpicref->pts;
87 else
88 second->pts = AV_NOPTS_VALUE;
89
90 ret = ff_filter_frame(outlink, second);
91 if (ret < 0)
92 return ret;
93clone:
94 s->second = av_frame_clone(inpicref);
95 if (!s->second)
96 return AVERROR(ENOMEM);
97 }
98
99 extract_field(inpicref, s->nb_planes, !(inpicref->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST));
100
101 if (inpicref->pts != AV_NOPTS_VALUE)
102 inpicref->pts *= 2;
103
104 return ff_filter_frame(outlink, inpicref);
105}
106
107static int flush_frame(AVFilterLink *outlink, int64_t pts, int64_t *out_pts)
108{
109 AVFilterContext *ctx = outlink->src;
110 SeparateFieldsContext *s = ctx->priv;
111 int ret = 0;
112
113 if (s->second) {
114 *out_pts = s->second->pts += pts;
115 extract_field(s->second, s->nb_planes, !!(s->second->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST));
116 ret = ff_filter_frame(outlink, s->second);
117 s->second = NULL;
118 }
119
120 return ret;
121}
122
124{
125 AVFilterLink *inlink = ctx->inputs[0];
126 AVFilterLink *outlink = ctx->outputs[0];
127 AVFrame *in;
128 int64_t pts;
129 int ret, status;
130
131 FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
132
133 ret = ff_inlink_consume_frame(inlink, &in);
134 if (ret < 0)
135 return ret;
136 if (ret > 0)
137 return filter_frame(inlink, in);
138
139 if (ff_inlink_acknowledge_status(inlink, &status, &pts)) {
140 if (status == AVERROR_EOF) {
141 int64_t out_pts = pts;
142
143 ret = flush_frame(outlink, pts, &out_pts);
144 ff_outlink_set_status(outlink, status, out_pts);
145 return ret;
146 }
147 }
148
149 FF_FILTER_FORWARD_WANTED(outlink, inlink);
150
151 return FFERROR_NOT_READY;
152}
153
155{
156 SeparateFieldsContext *s = ctx->priv;
157
158 av_frame_free(&s->second);
159}
160
162 {
163 .name = "default",
164 .type = AVMEDIA_TYPE_VIDEO,
165 .config_props = config_props_output,
166 },
167};
168
170 .p.name = "separatefields",
171 .p.description = NULL_IF_CONFIG_SMALL("Split input video frames into fields."),
172 .priv_size = sizeof(SeparateFieldsContext),
174 .uninit = uninit,
177};
const FFFilter ff_vf_separatefields
static AVFormatContext * ctx
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition avfilter.c:1467
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
Definition avfilter.c:1520
Main libavfilter public API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static AVFrame * frame
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition frame.h:695
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
Definition frame.h:700
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition frame.c:483
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
cl_device_type type
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int activate(AVBitStreamFilterContext *ctx)
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
#define FF_FILTER_FORWARD_WANTED(outlink, inlink)
Forward the frame_wanted_out flag from an output link to an input link.
Definition filters.h:694
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition filters.h:629
#define FFERROR_NOT_READY
Filters implementation helper functions and internal structures.
Definition filters.h:34
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
Definition filters.h:639
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition filters.h:199
#define av_cold
Definition attributes.h:117
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3500
An instance of a filter.
Definition avfilter.h:273
A filter pad used for either input or output.
Definition filters.h:40
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition frame.h:574
int height
Definition frame.h:544
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition frame.h:716
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
#define av_log(a,...)
static int64_t pts
static int config_props_output(AVFilterLink *outlink)
static int flush_frame(AVFilterLink *outlink, int64_t pts, int64_t *out_pts)
static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
static const AVFilterPad separatefields_outputs[]
static void extract_field(AVFrame *frame, int nb_planes, int type)
static int activate(AVFilterContext *ctx)
static av_cold void uninit(AVFilterContext *ctx)
static int config_props_output(AVFilterLink *outlink)
const AVFilterPad ff_video_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_VIDEO.
Definition video.c:37