[FFmpeg-devel,5/5] ffmpeg: send EOF pts to filters.

Submitted by Nicolas George on Sept. 7, 2017, 8:59 a.m.

Details

Message ID 20170907085939.21770-5-george@nsup.org
State New
Headers show

Commit Message

Nicolas George Sept. 7, 2017, 8:59 a.m.
Signed-off-by: Nicolas George <george@nsup.org>
---
 ffmpeg.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

Comments

Michael Niedermayer Sept. 7, 2017, 11:11 p.m.
On Thu, Sep 07, 2017 at 10:59:39AM +0200, Nicolas George wrote:
> Signed-off-by: Nicolas George <george@nsup.org>
> ---
>  ffmpeg.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)

should be ok

thanks

[...]
Thomas Mundt Oct. 4, 2017, 12:36 a.m.
Hi Nicolas,

2017-09-07 10:59 GMT+02:00 Nicolas George <george@nsup.org>:

> Signed-off-by: Nicolas George <george@nsup.org>
> ---
>  ffmpeg.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/ffmpeg.c b/ffmpeg.c
> index b95addd277..1d248bc269 100644
> --- a/ffmpeg.c
> +++ b/ffmpeg.c
> @@ -2223,14 +2223,14 @@ static int ifilter_send_frame(InputFilter
> *ifilter, AVFrame *frame)
>      return 0;
>  }
>
> -static int ifilter_send_eof(InputFilter *ifilter)
> +static int ifilter_send_eof(InputFilter *ifilter, int64_t pts)
>  {
>      int i, j, ret;
>
>      ifilter->eof = 1;
>
>      if (ifilter->filter) {
> -        ret = av_buffersrc_add_frame_flags(ifilter->filter, NULL,
> AV_BUFFERSRC_FLAG_PUSH);
> +        ret = av_buffersrc_close(ifilter->filter, pts,
> AV_BUFFERSRC_FLAG_PUSH);
>          if (ret < 0)
>              return ret;
>      } else {
> @@ -2581,8 +2581,12 @@ out:
>  static int send_filter_eof(InputStream *ist)
>  {
>      int i, ret;
> +    /* TODO keep pts also in stream time base to avoid converting back */
> +    int64_t pts = av_rescale_q_rnd(ist->pts, AV_TIME_BASE_Q,
> ist->st->time_base,
> +                                   AV_ROUND_NEAR_INF |
> AV_ROUND_PASS_MINMAX);
> +
>      for (i = 0; i < ist->nb_filters; i++) {
> -        ret = ifilter_send_eof(ist->filters[i]);
> +        ret = ifilter_send_eof(ist->filters[i], pts);
>          if (ret < 0)
>              return ret;
>      }
>

The sended pts always seems to refer to the input time base.
When a filter changes the time base, the EOF pts becomes wrong for
subsequent filters in the chain.
E.g. when using vf_fps behind vf_yadif=1 with interlaced input, the sended
EOF pts is only half of the expected pts.

I tried to find a solution, but without success.
Do you have an idea?

Regards,
Thomas


<http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail>
Virenfrei.
www.avg.com
<http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail>
<#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
Sasi Inguva Oct. 6, 2017, 3:01 a.m.
I've encountered the same problem, and tracked it to guess_status_pts
function which tries to take the end timestamp from the input links
however without converting it to correct time base. Sent a patch, PTAL.

On Tue, Oct 3, 2017 at 5:36 PM, Thomas Mundt <tmundt75@gmail.com> wrote:

> Hi Nicolas,
>
> 2017-09-07 10:59 GMT+02:00 Nicolas George <george@nsup.org>:
>
> > Signed-off-by: Nicolas George <george@nsup.org>
> > ---
> >  ffmpeg.c | 10 +++++++---
> >  1 file changed, 7 insertions(+), 3 deletions(-)
> >
> > diff --git a/ffmpeg.c b/ffmpeg.c
> > index b95addd277..1d248bc269 100644
> > --- a/ffmpeg.c
> > +++ b/ffmpeg.c
> > @@ -2223,14 +2223,14 @@ static int ifilter_send_frame(InputFilter
> > *ifilter, AVFrame *frame)
> >      return 0;
> >  }
> >
> > -static int ifilter_send_eof(InputFilter *ifilter)
> > +static int ifilter_send_eof(InputFilter *ifilter, int64_t pts)
> >  {
> >      int i, j, ret;
> >
> >      ifilter->eof = 1;
> >
> >      if (ifilter->filter) {
> > -        ret = av_buffersrc_add_frame_flags(ifilter->filter, NULL,
> > AV_BUFFERSRC_FLAG_PUSH);
> > +        ret = av_buffersrc_close(ifilter->filter, pts,
> > AV_BUFFERSRC_FLAG_PUSH);
> >          if (ret < 0)
> >              return ret;
> >      } else {
> > @@ -2581,8 +2581,12 @@ out:
> >  static int send_filter_eof(InputStream *ist)
> >  {
> >      int i, ret;
> > +    /* TODO keep pts also in stream time base to avoid converting back
> */
> > +    int64_t pts = av_rescale_q_rnd(ist->pts, AV_TIME_BASE_Q,
> > ist->st->time_base,
> > +                                   AV_ROUND_NEAR_INF |
> > AV_ROUND_PASS_MINMAX);
> > +
> >      for (i = 0; i < ist->nb_filters; i++) {
> > -        ret = ifilter_send_eof(ist->filters[i]);
> > +        ret = ifilter_send_eof(ist->filters[i], pts);
> >          if (ret < 0)
> >              return ret;
> >      }
> >
>
> The sended pts always seems to refer to the input time base.
> When a filter changes the time base, the EOF pts becomes wrong for
> subsequent filters in the chain.
> E.g. when using vf_fps behind vf_yadif=1 with interlaced input, the sended
> EOF pts is only half of the expected pts.
>
> I tried to find a solution, but without success.
> Do you have an idea?
>
> Regards,
> Thomas
>
>
> <http://www.avg.com/email-signature?utm_medium=email&
> utm_source=link&utm_campaign=sig-email&utm_content=webmail>
> Virenfrei.
> www.avg.com
> <http://www.avg.com/email-signature?utm_medium=email&
> utm_source=link&utm_campaign=sig-email&utm_content=webmail>
> <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>

Patch hide | download patch | download mbox

diff --git a/ffmpeg.c b/ffmpeg.c
index b95addd277..1d248bc269 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -2223,14 +2223,14 @@  static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
     return 0;
 }
 
-static int ifilter_send_eof(InputFilter *ifilter)
+static int ifilter_send_eof(InputFilter *ifilter, int64_t pts)
 {
     int i, j, ret;
 
     ifilter->eof = 1;
 
     if (ifilter->filter) {
-        ret = av_buffersrc_add_frame_flags(ifilter->filter, NULL, AV_BUFFERSRC_FLAG_PUSH);
+        ret = av_buffersrc_close(ifilter->filter, pts, AV_BUFFERSRC_FLAG_PUSH);
         if (ret < 0)
             return ret;
     } else {
@@ -2581,8 +2581,12 @@  out:
 static int send_filter_eof(InputStream *ist)
 {
     int i, ret;
+    /* TODO keep pts also in stream time base to avoid converting back */
+    int64_t pts = av_rescale_q_rnd(ist->pts, AV_TIME_BASE_Q, ist->st->time_base,
+                                   AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
+
     for (i = 0; i < ist->nb_filters; i++) {
-        ret = ifilter_send_eof(ist->filters[i]);
+        ret = ifilter_send_eof(ist->filters[i], pts);
         if (ret < 0)
             return ret;
     }