diff mbox

[FFmpeg-devel,2/2] ffmpeg: use reordered duration for stream PTS.

Message ID 20170403125215.16031-2-george@nsup.org
State Superseded
Headers show

Commit Message

Nicolas George April 3, 2017, 12:52 p.m. UTC
Signed-off-by: Nicolas George <george@nsup.org>
---
 ffmpeg.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)


Not sure if this is correct, the timestamp handling is awfully complicated.
But FATE succeeds and the result is a correct value of next_pts after the
last frame with a VFR file.

Comments

wm4 April 3, 2017, 1:03 p.m. UTC | #1
On Mon,  3 Apr 2017 14:52:15 +0200
Nicolas George <george@nsup.org> wrote:

> Signed-off-by: Nicolas George <george@nsup.org>
> ---
>  ffmpeg.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> 
> Not sure if this is correct, the timestamp handling is awfully complicated.
> But FATE succeeds and the result is a correct value of next_pts after the
> last frame with a VFR file.
> 
> 
> diff --git a/ffmpeg.c b/ffmpeg.c
> index 02ff073615..f67896d439 100644
> --- a/ffmpeg.c
> +++ b/ffmpeg.c
> @@ -2356,7 +2356,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output,
>      return err < 0 ? err : ret;
>  }
>  
> -static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int eof,
> +static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int *duration_pts, int eof,
>                          int *decode_failed)
>  {
>      AVFrame *decoded_frame;
> @@ -2447,6 +2447,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int eo
>      ist->hwaccel_retrieved_pix_fmt = decoded_frame->format;
>  
>      best_effort_timestamp= av_frame_get_best_effort_timestamp(decoded_frame);
> +    *duration_pts = decoded_frame->pkt_duration;
>  
>      if (ist->framerate.num)
>          best_effort_timestamp = ist->cfr_next_pts++;
> @@ -2617,6 +2618,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
>      // while we have more to decode or while the decoder did output something on EOF
>      while (ist->decoding_needed) {
>          int duration_dts = 0;
> +        int duration_pts = 0;
>          int got_output = 0;
>          int decode_failed = 0;
>  
> @@ -2629,7 +2631,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
>                                     &decode_failed);
>              break;
>          case AVMEDIA_TYPE_VIDEO:
> -            ret = decode_video    (ist, repeating ? NULL : &avpkt, &got_output, !pkt,
> +            ret = decode_video    (ist, repeating ? NULL : &avpkt, &got_output, &duration_pts, !pkt,
>                                     &decode_failed);
>              if (!repeating || !pkt || got_output) {
>                  if (pkt && pkt->duration) {
> @@ -2648,7 +2650,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
>              }
>  
>              if (got_output)
> -                ist->next_pts += duration_dts; //FIXME the duration is not correct in some cases
> +                ist->next_pts += av_rescale_q(duration_pts, ist->st->time_base, AV_TIME_BASE_Q);
>              break;
>          case AVMEDIA_TYPE_SUBTITLE:
>              if (repeating)

Not all decoders can set AVFrame.pkt_duration reliably.
diff mbox

Patch

diff --git a/ffmpeg.c b/ffmpeg.c
index 02ff073615..f67896d439 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -2356,7 +2356,7 @@  static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output,
     return err < 0 ? err : ret;
 }
 
-static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int eof,
+static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int *duration_pts, int eof,
                         int *decode_failed)
 {
     AVFrame *decoded_frame;
@@ -2447,6 +2447,7 @@  static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int eo
     ist->hwaccel_retrieved_pix_fmt = decoded_frame->format;
 
     best_effort_timestamp= av_frame_get_best_effort_timestamp(decoded_frame);
+    *duration_pts = decoded_frame->pkt_duration;
 
     if (ist->framerate.num)
         best_effort_timestamp = ist->cfr_next_pts++;
@@ -2617,6 +2618,7 @@  static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
     // while we have more to decode or while the decoder did output something on EOF
     while (ist->decoding_needed) {
         int duration_dts = 0;
+        int duration_pts = 0;
         int got_output = 0;
         int decode_failed = 0;
 
@@ -2629,7 +2631,7 @@  static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
                                    &decode_failed);
             break;
         case AVMEDIA_TYPE_VIDEO:
-            ret = decode_video    (ist, repeating ? NULL : &avpkt, &got_output, !pkt,
+            ret = decode_video    (ist, repeating ? NULL : &avpkt, &got_output, &duration_pts, !pkt,
                                    &decode_failed);
             if (!repeating || !pkt || got_output) {
                 if (pkt && pkt->duration) {
@@ -2648,7 +2650,7 @@  static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
             }
 
             if (got_output)
-                ist->next_pts += duration_dts; //FIXME the duration is not correct in some cases
+                ist->next_pts += av_rescale_q(duration_pts, ist->st->time_base, AV_TIME_BASE_Q);
             break;
         case AVMEDIA_TYPE_SUBTITLE:
             if (repeating)