[FFmpeg-cvslog] avfilter/vf_separatefields: do not reset pts to 0

Paul B Mahol git at videolan.org
Sat Oct 12 17:10:40 CEST 2013


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Sat Oct 12 14:55:42 2013 +0000| [1d8ce109e91d8e8f87676a2f24af18f14fa297a5] | committer: Paul B Mahol

avfilter/vf_separatefields: do not reset pts to 0

Signed-off-by: Paul B Mahol <onemda at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1d8ce109e91d8e8f87676a2f24af18f14fa297a5
---

 libavfilter/vf_separatefields.c |   79 +++++++++++++++++++++++++++------------
 1 file changed, 56 insertions(+), 23 deletions(-)

diff --git a/libavfilter/vf_separatefields.c b/libavfilter/vf_separatefields.c
index d37ca9a..00ecac1 100644
--- a/libavfilter/vf_separatefields.c
+++ b/libavfilter/vf_separatefields.c
@@ -24,7 +24,7 @@
 
 typedef struct {
     int nb_planes;
-    double ts_unit;
+    AVFrame *second;
 } SeparateFieldsContext;
 
 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->w = inlink->w;
     outlink->h = inlink->h / 2;
-    sf->ts_unit = av_q2d(av_inv_q(av_mul_q(outlink->frame_rate, outlink->time_base)));
 
     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)
 {
     AVFilterContext *ctx = inlink->dst;
     SeparateFieldsContext *sf = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
-    AVFrame *second;
-    int i, ret;
+    int ret;
 
     inpicref->height = outlink->h;
     inpicref->interlaced_frame = 0;
 
-    second = av_frame_clone(inpicref);
-    if (!second)
-        return AVERROR(ENOMEM);
+    if (!sf->second) {
+        goto clone;
+    } else {
+        AVFrame *second = sf->second;
 
-    for (i = 0; i < sf->nb_planes; i++) {
-        if (!inpicref->top_field_first)
-            inpicref->data[i] = inpicref->data[i] + inpicref->linesize[i];
+        extract_field(second, sf->nb_planes, second->top_field_first);
+
+        if (second->pts != AV_NOPTS_VALUE &&
+            inpicref->pts != AV_NOPTS_VALUE)
+            second->pts += inpicref->pts;
         else
-            second->data[i] = second->data[i] + second->linesize[i];
-        inpicref->linesize[i] *= 2;
-        second->linesize[i]   *= 2;
+            second->pts = AV_NOPTS_VALUE;
+
+        ret = ff_filter_frame(outlink, second);
+        if (ret < 0)
+            return ret;
+clone:
+        sf->second = av_frame_clone(inpicref);
+        if (!sf->second)
+            return AVERROR(ENOMEM);
     }
 
-    inpicref->pts = outlink->frame_count * sf->ts_unit;
-    ret = ff_filter_frame(outlink, inpicref);
-    if (ret < 0) {
-        av_frame_free(&second);
-        return ret;
+    extract_field(inpicref, sf->nb_planes, !inpicref->top_field_first);
+
+    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;
     }
 
-    second->pts = outlink->frame_count * sf->ts_unit;
-    return ff_filter_frame(outlink, second);
+    return ret;
 }
 
 static const AVFilterPad separatefields_inputs[] = {
@@ -97,9 +129,10 @@ static const AVFilterPad separatefields_inputs[] = {
 
 static const AVFilterPad separatefields_outputs[] = {
     {
-        .name         = "default",
-        .type         = AVMEDIA_TYPE_VIDEO,
-        .config_props = config_props_output,
+        .name          = "default",
+        .type          = AVMEDIA_TYPE_VIDEO,
+        .config_props  = config_props_output,
+        .request_frame = request_frame,
     },
     { NULL }
 };



More information about the ffmpeg-cvslog mailing list