[vlc-devel] [PATCH] [codec/dirac.c] Fix aspect ratio signalling and presentation time stamps

David Flynn davidf+nntp at woaf.net
Sun Jun 29 13:44:00 CEST 2008


- Add aspect ratio calculation rather than fixed 4:3
- Do not set p_pic->date = p_block->i_pts, p_block will be several frames
  ahead of p_pic, worse it isn't in presentation order.  Since there is
  no method of tagging input blocks with PTS through the decoder, fake
  the PTS at output based upon the an initial PTS and frame rate.

Signed-off-by: David Flynn <davidf at woaf.net>
---
 modules/codec/dirac.c |   33 +++++++++++++++++++++++++++++++--
 1 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/modules/codec/dirac.c b/modules/codec/dirac.c
index f621090..d2ccbf5 100644
--- a/modules/codec/dirac.c
+++ b/modules/codec/dirac.c
@@ -46,6 +46,8 @@ struct decoder_sys_t
     /*
      * Dirac properties
      */
+    mtime_t i_lastpts;
+    mtime_t i_frame_pts_delta;
     dirac_decoder_t *p_dirac;
 };
 
@@ -113,6 +115,8 @@ static int OpenDecoder( vlc_object_t *p_this )
         return VLC_ENOMEM;
 
     p_sys->p_dirac = p_dirac;
+    p_sys->i_lastpts = -1;
+    p_sys->i_frame_pts_delta = 0;
 
     /* Set output properties */
     p_dec->fmt_out.i_cat = VIDEO_ES;
@@ -160,7 +164,16 @@ static picture_t *GetNewPicture( decoder_t *p_dec )
     p_dec->fmt_out.video.i_width = p_sys->p_dirac->src_params.width;
     p_dec->fmt_out.video.i_visible_height =
     p_dec->fmt_out.video.i_height = p_sys->p_dirac->src_params.height;
-    p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;
+
+    double f_aspect = (double)
+        ( p_sys->p_dirac->src_params.width
+          * p_sys->p_dirac->src_params.pix_asr.numerator )
+        /
+        ( p_sys->p_dirac->src_params.height
+          * p_sys->p_dirac->src_params.pix_asr.denominator )
+        ;
+
+    p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * f_aspect;
 
     p_dec->fmt_out.video.i_frame_rate =
         p_sys->p_dirac->src_params.frame_rate.numerator;
@@ -258,6 +271,11 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
                      (float)p_sys->p_dirac->src_params.frame_rate.numerator/
                      p_sys->p_dirac->src_params.frame_rate.denominator );
 
+            p_sys->i_frame_pts_delta =
+                INT64_C(1000000)
+                * p_sys->p_dirac->src_params.frame_rate.denominator
+                / p_sys->p_dirac->src_params.frame_rate.numerator;
+
             FreeFrameBuffer( p_sys->p_dirac );
             buf[0] = malloc( p_sys->p_dirac->src_params.width *
                              p_sys->p_dirac->src_params.height );
@@ -281,10 +299,21 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 
             /* Picture available for display */
             p_pic = GetNewPicture( p_dec );
+
+            /* This is a nasty hack to work around the lack of PTS tagging
+             * for input buffers/pictures with this plugin.
+             * - If the this is the first time we notice an input block with
+             *   a PTS, store it and use it.
+             * - For all subsequent output frames, add a delta to the PTS
+             *   and use that instead.
+             */
             p_pic->date = p_block->i_pts > 0 ? p_block->i_pts : p_block->i_dts;
+            if ( p_sys->i_lastpts >= 0 )
+                p_pic->date = p_sys->i_lastpts + p_sys->i_frame_pts_delta;
+            p_sys->i_lastpts = p_pic->date;
             p_pic->b_force = 1; // HACK
+
             return p_pic;
-            break;
 
         case STATE_INVALID:
             msg_Dbg( p_dec, "STATE_INVALID" );
-- 
1.5.4.3





More information about the vlc-devel mailing list