avfilter/vf_stereo3d: get rid of ts_unit hack
authorPaul B Mahol <onemda@gmail.com>
Wed, 16 Dec 2015 11:36:21 +0000 (12:36 +0100)
committerPaul B Mahol <onemda@gmail.com>
Wed, 16 Dec 2015 12:00:46 +0000 (13:00 +0100)
Signed-off-by: Paul B Mahol <onemda@gmail.com>
libavfilter/vf_stereo3d.c

index 224db30..f207d92 100644 (file)
@@ -148,7 +148,6 @@ typedef struct Stereo3DContext {
     int hsub, vsub;
     int pixstep[4];
     AVFrame *prev;
-    double ts_unit;
     int blanks;
     int in_off_left[4], in_off_right[4];
     Stereo3DDSPContext dsp;
@@ -544,7 +543,6 @@ static int config_output(AVFilterLink *outlink)
         return ret;
     s->nb_planes = av_pix_fmt_count_planes(outlink->format);
     av_image_fill_max_pixsteps(s->pixstep, NULL, desc);
-    s->ts_unit = av_q2d(av_inv_q(av_mul_q(outlink->frame_rate, outlink->time_base)));
     s->pheight[1] = s->pheight[2] = FF_CEIL_RSHIFT(s->height, desc->log2_chroma_h);
     s->pheight[0] = s->pheight[3] = s->height;
     s->hsub = desc->log2_chroma_w;
@@ -593,11 +591,21 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
     AVFilterLink *outlink = ctx->outputs[0];
     AVFrame *out, *oleft, *oright, *ileft, *iright;
     int out_off_left[4], out_off_right[4];
-    int i;
+    int i, ret;
 
     if (s->in.format == s->out.format)
         return ff_filter_frame(outlink, inpicref);
 
+    switch (s->out.format) {
+    case ALTERNATING_LR:
+    case ALTERNATING_RL:
+        if (!s->prev) {
+            s->prev = inpicref;
+            return 0;
+        }
+        break;
+    };
+
     switch (s->in.format) {
     case ALTERNATING_LR:
     case ALTERNATING_RL:
@@ -624,8 +632,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
          s->in.format == ABOVE_BELOW_RL ||
          s->in.format == ABOVE_BELOW_2_LR ||
          s->in.format == ABOVE_BELOW_2_RL)) {
-        oright = av_frame_clone(inpicref);
-        oleft  = av_frame_clone(inpicref);
+        oright = av_frame_clone(s->prev);
+        oleft  = av_frame_clone(s->prev);
         if (!oright || !oleft) {
             av_frame_free(&oright);
             av_frame_free(&oleft);
@@ -649,6 +657,25 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
             av_frame_free(&inpicref);
             return AVERROR(ENOMEM);
         }
+    } else if ((s->out.format == MONO_L && s->in.format == ALTERNATING_LR) ||
+               (s->out.format == MONO_R && s->in.format == ALTERNATING_RL)) {
+        s->prev->pts /= 2;
+        ret = ff_filter_frame(outlink, s->prev);
+        av_frame_free(&inpicref);
+        s->prev = NULL;
+        return ret;
+    } else if ((s->out.format == MONO_L && s->in.format == ALTERNATING_RL) ||
+               (s->out.format == MONO_R && s->in.format == ALTERNATING_LR)) {
+        av_frame_free(&s->prev);
+        inpicref->pts /= 2;
+        return ff_filter_frame(outlink, inpicref);
+    } else if ((s->out.format == ALTERNATING_LR && s->in.format == ALTERNATING_RL) ||
+               (s->out.format == ALTERNATING_RL && s->in.format == ALTERNATING_LR)) {
+        FFSWAP(int64_t, s->prev->pts, inpicref->pts);
+        ff_filter_frame(outlink, inpicref);
+        ret = ff_filter_frame(outlink, s->prev);
+        s->prev = NULL;
+        return ret;
     } else {
         out = oleft = oright = ff_get_video_buffer(outlink, outlink->w, outlink->h);
         if (!out) {
@@ -667,7 +694,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
                 av_frame_free(&inpicref);
                 return AVERROR(ENOMEM);
             }
-            av_frame_copy_props(oright, inpicref);
+            av_frame_copy_props(oright, s->prev);
         }
     }
 
@@ -902,18 +929,23 @@ copy:
         av_assert0(0);
     }
 
-    av_frame_free(&inpicref);
-    av_frame_free(&s->prev);
     if (oright != oleft) {
         if (s->out.format == ALTERNATING_LR)
             FFSWAP(AVFrame *, oleft, oright);
-        oright->pts = outlink->frame_count * s->ts_unit;
+        oright->pts = s->prev->pts * 2;
         ff_filter_frame(outlink, oright);
         out = oleft;
-        oleft->pts = outlink->frame_count * s->ts_unit;
+        oleft->pts = s->prev->pts + inpicref->pts;
+        av_frame_free(&s->prev);
+        s->prev = inpicref;
     } else if (s->in.format == ALTERNATING_LR ||
                s->in.format == ALTERNATING_RL) {
-        out->pts = outlink->frame_count * s->ts_unit;
+        out->pts = s->prev->pts / 2;
+        av_frame_free(&s->prev);
+        av_frame_free(&inpicref);
+    } else {
+        av_frame_free(&s->prev);
+        av_frame_free(&inpicref);
     }
     return ff_filter_frame(outlink, out);
 }