summaryrefslogtreecommitdiff
path: root/libavfilter/vf_detelecine.c
diff options
context:
space:
mode:
authorBenjamin Steffes <benjaminst123@gmail.com>2016-03-17 23:09:59 +0100
committerMichael Niedermayer <michael@niedermayer.cc>2016-03-19 03:58:47 +0100
commitbe482e5165256091ecdd8aaa4cf7376abc97cf05 (patch)
treea16f7a718647ce20ef09f1e9e7d45a6a6470c27e /libavfilter/vf_detelecine.c
parent7af3f27008b8406143a544f90590fd335806c1d7 (diff)
Fix detelecine filter for patterns containing 1
Signed-off-by: Benjamin Steffes <benjaminst123@gmail.com> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavfilter/vf_detelecine.c')
-rw-r--r--libavfilter/vf_detelecine.c78
1 files changed, 53 insertions, 25 deletions
diff --git a/libavfilter/vf_detelecine.c b/libavfilter/vf_detelecine.c
index f5ae350c05..16230f1abd 100644
--- a/libavfilter/vf_detelecine.c
+++ b/libavfilter/vf_detelecine.c
@@ -49,7 +49,7 @@ typedef struct {
int planeheight[4];
int stride[4];
- AVFrame *frame;
+ AVFrame *frame[2];
AVFrame *temp;
} DetelecineContext;
@@ -140,8 +140,12 @@ static int config_input(AVFilterLink *inlink)
if (!s->temp)
return AVERROR(ENOMEM);
- s->frame = ff_get_video_buffer(inlink, inlink->w, inlink->h);
- if (!s->frame)
+ s->frame[0] = ff_get_video_buffer(inlink, inlink->w, inlink->h);
+ if (!s->frame[0])
+ return AVERROR(ENOMEM);
+
+ s->frame[1] = ff_get_video_buffer(inlink, inlink->w, inlink->h);
+ if (!s->frame[1])
return AVERROR(ENOMEM);
if ((ret = av_image_fill_linesizes(s->stride, inlink->format, inlink->w)) < 0)
@@ -220,18 +224,39 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
return 0;
}
+ if (len == 1 && s->occupied) {
+ s->occupied = 0;
+ // output THIS image as-is
+ for (i = 0; i < s->nb_planes; i++)
+ av_image_copy_plane(s->frame[out]->data[i], s->frame[out]->linesize[i],
+ s->temp->data[i], s->temp->linesize[i],
+ s->stride[i],
+ s->planeheight[i]);
+ len = 0;
+ while(!len && s->pattern[s->pattern_pos]) {
+ len = s->pattern[s->pattern_pos] - '0';
+ s->pattern_pos++;
+ }
+
+ if (!s->pattern[s->pattern_pos])
+ s->pattern_pos = 0;
+
+ s->occupied = 0;
+ ++out;
+ }
+
if (s->occupied) {
for (i = 0; i < s->nb_planes; i++) {
// fill in the EARLIER field from the new pic
- av_image_copy_plane(s->frame->data[i] + s->frame->linesize[i] * s->first_field,
- s->frame->linesize[i] * 2,
+ av_image_copy_plane(s->frame[out]->data[i] + s->frame[out]->linesize[i] * s->first_field,
+ s->frame[out]->linesize[i] * 2,
inpicref->data[i] + inpicref->linesize[i] * s->first_field,
inpicref->linesize[i] * 2,
s->stride[i],
(s->planeheight[i] - s->first_field + 1) / 2);
// fill in the LATER field from the buffered pic
- av_image_copy_plane(s->frame->data[i] + s->frame->linesize[i] * !s->first_field,
- s->frame->linesize[i] * 2,
+ av_image_copy_plane(s->frame[out]->data[i] + s->frame[out]->linesize[i] * !s->first_field,
+ s->frame[out]->linesize[i] * 2,
s->temp->data[i] + s->temp->linesize[i] * !s->first_field,
s->temp->linesize[i] * 2,
s->stride[i],
@@ -248,34 +273,36 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
}
s->occupied = 1;
}
- out = 1;
+ ++out;
len = (len >= 3) ? len - 3 : 0;
} else {
if (len >= 2) {
// output THIS image as-is
for (i = 0; i < s->nb_planes; i++)
- av_image_copy_plane(s->frame->data[i], s->frame->linesize[i],
+ av_image_copy_plane(s->frame[out]->data[i], s->frame[out]->linesize[i],
inpicref->data[i], inpicref->linesize[i],
s->stride[i],
s->planeheight[i]);
len -= 2;
- out = 1;
+ ++out;
} else if (len == 1) {
- // fill in the EARLIER field from the new pic
- for (i = 0; i < s->nb_planes; i++) {
- av_image_copy_plane(s->frame->data[i] +
- s->frame->linesize[i] * s->first_field,
- s->frame->linesize[i] * 2,
- inpicref->data[i] +
- inpicref->linesize[i] * s->first_field,
- inpicref->linesize[i] * 2, s->stride[i],
- (s->planeheight[i] - s->first_field + 1) / 2);
- }
+ // output THIS image as-is
+ for (i = 0; i < s->nb_planes; i++)
+ av_image_copy_plane(s->frame[out]->data[i], s->frame[out]->linesize[i],
+ inpicref->data[i], inpicref->linesize[i],
+ s->stride[i],
+ s->planeheight[i]);
- // TODO: not sure about the other field
+ for (i = 0; i < s->nb_planes; i++) {
+ av_image_copy_plane(s->temp->data[i], s->temp->linesize[i],
+ inpicref->data[i], inpicref->linesize[i],
+ s->stride[i],
+ s->planeheight[i]);
+ }
+ s->occupied = 1;
len--;
- out = 1;
+ ++out;
}
}
@@ -287,8 +314,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
}
s->nskip_fields = len;
- if (out) {
- AVFrame *frame = av_frame_clone(s->frame);
+ for (int i = 0; i < out; ++i) {
+ AVFrame *frame = av_frame_clone(s->frame[i]);
if (!frame) {
av_frame_free(&inpicref);
@@ -312,7 +339,8 @@ static av_cold void uninit(AVFilterContext *ctx)
DetelecineContext *s = ctx->priv;
av_frame_free(&s->temp);
- av_frame_free(&s->frame);
+ av_frame_free(&s->frame[0]);
+ av_frame_free(&s->frame[1]);
}
static const AVFilterPad detelecine_inputs[] = {