mirror of https://git.ffmpeg.org/ffmpeg.git
avfilter/vf_separatefields: do not reset pts to 0
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
parent
8de021fabe
commit
1d8ce109e9
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int nb_planes;
|
int nb_planes;
|
||||||
double ts_unit;
|
AVFrame *second;
|
||||||
} SeparateFieldsContext;
|
} SeparateFieldsContext;
|
||||||
|
|
||||||
static int config_props_output(AVFilterLink *outlink)
|
static int config_props_output(AVFilterLink *outlink)
|
||||||
|
@ -46,44 +46,76 @@ static int config_props_output(AVFilterLink *outlink)
|
||||||
outlink->frame_rate.den = inlink->frame_rate.den;
|
outlink->frame_rate.den = inlink->frame_rate.den;
|
||||||
outlink->w = inlink->w;
|
outlink->w = inlink->w;
|
||||||
outlink->h = inlink->h / 2;
|
outlink->h = inlink->h / 2;
|
||||||
sf->ts_unit = av_q2d(av_inv_q(av_mul_q(outlink->frame_rate, outlink->time_base)));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void extract_field(AVFrame *frame, int nb_planes, int type)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < nb_planes; i++) {
|
||||||
|
if (type)
|
||||||
|
frame->data[i] = frame->data[i] + frame->linesize[i];
|
||||||
|
frame->linesize[i] *= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
|
static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
|
||||||
{
|
{
|
||||||
AVFilterContext *ctx = inlink->dst;
|
AVFilterContext *ctx = inlink->dst;
|
||||||
SeparateFieldsContext *sf = ctx->priv;
|
SeparateFieldsContext *sf = ctx->priv;
|
||||||
AVFilterLink *outlink = ctx->outputs[0];
|
AVFilterLink *outlink = ctx->outputs[0];
|
||||||
AVFrame *second;
|
int ret;
|
||||||
int i, ret;
|
|
||||||
|
|
||||||
inpicref->height = outlink->h;
|
inpicref->height = outlink->h;
|
||||||
inpicref->interlaced_frame = 0;
|
inpicref->interlaced_frame = 0;
|
||||||
|
|
||||||
second = av_frame_clone(inpicref);
|
if (!sf->second) {
|
||||||
if (!second)
|
goto clone;
|
||||||
return AVERROR(ENOMEM);
|
} else {
|
||||||
|
AVFrame *second = sf->second;
|
||||||
|
|
||||||
for (i = 0; i < sf->nb_planes; i++) {
|
extract_field(second, sf->nb_planes, second->top_field_first);
|
||||||
if (!inpicref->top_field_first)
|
|
||||||
inpicref->data[i] = inpicref->data[i] + inpicref->linesize[i];
|
if (second->pts != AV_NOPTS_VALUE &&
|
||||||
|
inpicref->pts != AV_NOPTS_VALUE)
|
||||||
|
second->pts += inpicref->pts;
|
||||||
else
|
else
|
||||||
second->data[i] = second->data[i] + second->linesize[i];
|
second->pts = AV_NOPTS_VALUE;
|
||||||
inpicref->linesize[i] *= 2;
|
|
||||||
second->linesize[i] *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
inpicref->pts = outlink->frame_count * sf->ts_unit;
|
ret = ff_filter_frame(outlink, second);
|
||||||
ret = ff_filter_frame(outlink, inpicref);
|
if (ret < 0)
|
||||||
if (ret < 0) {
|
|
||||||
av_frame_free(&second);
|
|
||||||
return ret;
|
return ret;
|
||||||
|
clone:
|
||||||
|
sf->second = av_frame_clone(inpicref);
|
||||||
|
if (!sf->second)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
second->pts = outlink->frame_count * sf->ts_unit;
|
extract_field(inpicref, sf->nb_planes, !inpicref->top_field_first);
|
||||||
return ff_filter_frame(outlink, second);
|
|
||||||
|
if (inpicref->pts != AV_NOPTS_VALUE)
|
||||||
|
inpicref->pts *= 2;
|
||||||
|
|
||||||
|
return ff_filter_frame(outlink, inpicref);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int request_frame(AVFilterLink *outlink)
|
||||||
|
{
|
||||||
|
AVFilterContext *ctx = outlink->src;
|
||||||
|
SeparateFieldsContext *sf = ctx->priv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = ff_request_frame(ctx->inputs[0]);
|
||||||
|
if (ret == AVERROR_EOF && sf->second) {
|
||||||
|
sf->second->pts *= 2;
|
||||||
|
extract_field(sf->second, sf->nb_planes, sf->second->top_field_first);
|
||||||
|
ret = ff_filter_frame(outlink, sf->second);
|
||||||
|
sf->second = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const AVFilterPad separatefields_inputs[] = {
|
static const AVFilterPad separatefields_inputs[] = {
|
||||||
|
@ -100,6 +132,7 @@ static const AVFilterPad separatefields_outputs[] = {
|
||||||
.name = "default",
|
.name = "default",
|
||||||
.type = AVMEDIA_TYPE_VIDEO,
|
.type = AVMEDIA_TYPE_VIDEO,
|
||||||
.config_props = config_props_output,
|
.config_props = config_props_output,
|
||||||
|
.request_frame = request_frame,
|
||||||
},
|
},
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue