Commit be482e51 authored by Benjamin Steffes's avatar Benjamin Steffes Committed by Michael Niedermayer

Fix detelecine filter for patterns containing 1

Signed-off-by: 's avatarBenjamin Steffes <benjaminst123@gmail.com>
Signed-off-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent 7af3f270
...@@ -49,7 +49,7 @@ typedef struct { ...@@ -49,7 +49,7 @@ typedef struct {
int planeheight[4]; int planeheight[4];
int stride[4]; int stride[4];
AVFrame *frame; AVFrame *frame[2];
AVFrame *temp; AVFrame *temp;
} DetelecineContext; } DetelecineContext;
...@@ -140,8 +140,12 @@ static int config_input(AVFilterLink *inlink) ...@@ -140,8 +140,12 @@ static int config_input(AVFilterLink *inlink)
if (!s->temp) if (!s->temp)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
s->frame = ff_get_video_buffer(inlink, inlink->w, inlink->h); s->frame[0] = ff_get_video_buffer(inlink, inlink->w, inlink->h);
if (!s->frame) 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); return AVERROR(ENOMEM);
if ((ret = av_image_fill_linesizes(s->stride, inlink->format, inlink->w)) < 0) 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) ...@@ -220,18 +224,39 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
return 0; 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) { if (s->occupied) {
for (i = 0; i < s->nb_planes; i++) { for (i = 0; i < s->nb_planes; i++) {
// fill in the EARLIER field from the new pic // fill in the EARLIER field from the new pic
av_image_copy_plane(s->frame->data[i] + s->frame->linesize[i] * s->first_field, av_image_copy_plane(s->frame[out]->data[i] + s->frame[out]->linesize[i] * s->first_field,
s->frame->linesize[i] * 2, s->frame[out]->linesize[i] * 2,
inpicref->data[i] + inpicref->linesize[i] * s->first_field, inpicref->data[i] + inpicref->linesize[i] * s->first_field,
inpicref->linesize[i] * 2, inpicref->linesize[i] * 2,
s->stride[i], s->stride[i],
(s->planeheight[i] - s->first_field + 1) / 2); (s->planeheight[i] - s->first_field + 1) / 2);
// fill in the LATER field from the buffered pic // fill in the LATER field from the buffered pic
av_image_copy_plane(s->frame->data[i] + s->frame->linesize[i] * !s->first_field, av_image_copy_plane(s->frame[out]->data[i] + s->frame[out]->linesize[i] * !s->first_field,
s->frame->linesize[i] * 2, s->frame[out]->linesize[i] * 2,
s->temp->data[i] + s->temp->linesize[i] * !s->first_field, s->temp->data[i] + s->temp->linesize[i] * !s->first_field,
s->temp->linesize[i] * 2, s->temp->linesize[i] * 2,
s->stride[i], s->stride[i],
...@@ -248,34 +273,36 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) ...@@ -248,34 +273,36 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
} }
s->occupied = 1; s->occupied = 1;
} }
out = 1; ++out;
len = (len >= 3) ? len - 3 : 0; len = (len >= 3) ? len - 3 : 0;
} else { } else {
if (len >= 2) { if (len >= 2) {
// output THIS image as-is // output THIS image as-is
for (i = 0; i < s->nb_planes; i++) 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], inpicref->data[i], inpicref->linesize[i],
s->stride[i], s->stride[i],
s->planeheight[i]); s->planeheight[i]);
len -= 2; len -= 2;
out = 1; ++out;
} else if (len == 1) { } else if (len == 1) {
// fill in the EARLIER field from the new pic // output THIS image as-is
for (i = 0; i < s->nb_planes; i++) { for (i = 0; i < s->nb_planes; i++)
av_image_copy_plane(s->frame->data[i] + av_image_copy_plane(s->frame[out]->data[i], s->frame[out]->linesize[i],
s->frame->linesize[i] * s->first_field, inpicref->data[i], inpicref->linesize[i],
s->frame->linesize[i] * 2, s->stride[i],
inpicref->data[i] + s->planeheight[i]);
inpicref->linesize[i] * s->first_field,
inpicref->linesize[i] * 2, s->stride[i],
(s->planeheight[i] - s->first_field + 1) / 2);
}
// 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--; len--;
out = 1; ++out;
} }
} }
...@@ -287,8 +314,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) ...@@ -287,8 +314,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
} }
s->nskip_fields = len; s->nskip_fields = len;
if (out) { for (int i = 0; i < out; ++i) {
AVFrame *frame = av_frame_clone(s->frame); AVFrame *frame = av_frame_clone(s->frame[i]);
if (!frame) { if (!frame) {
av_frame_free(&inpicref); av_frame_free(&inpicref);
...@@ -312,7 +339,8 @@ static av_cold void uninit(AVFilterContext *ctx) ...@@ -312,7 +339,8 @@ static av_cold void uninit(AVFilterContext *ctx)
DetelecineContext *s = ctx->priv; DetelecineContext *s = ctx->priv;
av_frame_free(&s->temp); 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[] = { static const AVFilterPad detelecine_inputs[] = {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment