OSDN Git Service

fix a problem with point-to-point hanging when searching for start point
authorjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Wed, 26 May 2010 20:39:52 +0000 (20:39 +0000)
committerjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Wed, 26 May 2010 20:39:52 +0000 (20:39 +0000)
in reader, the timestamps were not being correctly adjusted for scr offset
before comparing to start time.  This could cause an early start in reader.
Then in sync, syncAudioWork stalled until the correct start of video was
found, causing the audio fifo to fill and stall the whole pipeline.

git-svn-id: svn://localhost/HandBrake/trunk@3329 b64f7644-9d1e-0410-96f1-a4d463321fa5

libhb/reader.c
libhb/sync.c

index bef7e1c..6e7f0e6 100644 (file)
@@ -266,24 +266,25 @@ static void ReaderFunc( void * _r )
     } 
     else if ( r->stream && r->job->pts_to_start )
     {
+        int64_t pts_to_start = r->job->pts_to_start;
         
         // Find out what the first timestamp of the stream is
         // and then seek to the appropriate offset from it
         if ( hb_stream_read( r->stream, ps ) )
         {
             if ( ps->start > 0 )
-                r->job->pts_to_start += ps->start;
+                pts_to_start += ps->start;
         }
         
-        if ( hb_stream_seek_ts( r->stream, r->job->pts_to_start ) >= 0 )
+        if ( hb_stream_seek_ts( r->stream, pts_to_start ) >= 0 )
         {
             // Seek takes us to the nearest I-frame before the timestamp
             // that we want.  So we will retrieve the start time of the
             // first packet we get, subtract that from pts_to_start, and
             // inspect the reset of the frames in sync.
             r->start_found = 2;
+            r->job->pts_to_start = pts_to_start;
         }
-
     } 
     else if( r->stream )
     {
@@ -348,6 +349,8 @@ static void ReaderFunc( void * _r )
             // want to start at.
             if ( ps->start > 0 && ps->start < r->job->pts_to_start )
                 r->job->pts_to_start -= ps->start;
+            else if ( ps->start >= r->job->pts_to_start )
+                r->job->pts_to_start = 0;
             r->start_found = 1;
           }
         }
@@ -405,44 +408,9 @@ static void ReaderFunc( void * _r )
             }
             if( fifos )
             {
-                if ( buf->start != -1 )
-                {
-                    int64_t start = buf->start - r->scr_offset;
-                    if ( !r->start_found )
-                        UpdateState( r, start );
-
-                    if ( !r->start_found &&
-                        r->job->pts_to_start && 
-                        buf->renderOffset != -1 &&
-                        start >= r->job->pts_to_start )
-                    {
-                        // pts_to_start point found
-                        // force a new scr offset computation
-                        stream_timing_t *st = find_st( r, buf );
-                        if ( st && 
-                            (st->is_audio ||
-                            ( st == r->stream_timing && !r->saw_audio ) ) )
-                        {
-                            // Re-zero our timestamps
-                            st->last = -st->average;
-                            new_scr_offset( r, buf );
-                            r->start_found = 1;
-                            r->job->pts_to_start = 0;
-                        }
-                    }
-                }
                 if ( buf->renderOffset != -1 )
                 {
-                    if ( r->scr_changes == r->demux.scr_changes )
-                    {
-                        // This packet is referenced to the same SCR as the last.
-                        // Adjust timestamp to remove the System Clock Reference
-                        // offset then update the average inter-packet time
-                        // for this stream.
-                        buf->renderOffset -= r->scr_offset;
-                        update_ipt( r, buf );
-                    }
-                    else
+                    if ( r->scr_changes != r->demux.scr_changes )
                     {
                         // This is the first audio or video packet after an SCR
                         // change. Compute a new scr offset that would make this
@@ -496,8 +464,43 @@ static void ReaderFunc( void * _r )
                 }
                 if ( buf->start != -1 )
                 {
+                    int64_t start = buf->start - r->scr_offset;
+                    if ( !r->start_found )
+                        UpdateState( r, start );
+
+                    if ( !r->start_found &&
+                        r->job->pts_to_start && 
+                        buf->renderOffset != -1 &&
+                        start >= r->job->pts_to_start )
+                    {
+                        // pts_to_start point found
+                        // force a new scr offset computation
+                        stream_timing_t *st = find_st( r, buf );
+                        if ( st && 
+                            (st->is_audio ||
+                            ( st == r->stream_timing && !r->saw_audio ) ) )
+                        {
+                            // Re-zero our timestamps
+                            st->last = -st->average;
+                            new_scr_offset( r, buf );
+                            r->start_found = 1;
+                            r->job->pts_to_start = 0;
+                        }
+                    }
                     buf->start -= r->scr_offset;
                 }
+                if ( buf->renderOffset != -1 )
+                {
+                    if ( r->scr_changes == r->demux.scr_changes )
+                    {
+                        // This packet is referenced to the same SCR as the last.
+                        // Adjust timestamp to remove the System Clock Reference
+                        // offset then update the average inter-packet time
+                        // for this stream.
+                        buf->renderOffset -= r->scr_offset;
+                        update_ipt( r, buf );
+                    }
+                }
                 if ( !r->start_found )
                 {
                     hb_buffer_close( &buf );
index 3601780..8972c72 100644 (file)
@@ -116,7 +116,7 @@ hb_work_object_t * hb_sync_init( hb_job_t * job )
     pv->common = calloc( 1, sizeof( hb_sync_common_t ) );
     pv->common->ref++;
     pv->common->mutex = hb_lock_init();
-    pv->common->audio_pts_thresh = 0;
+    pv->common->audio_pts_thresh = -1;
     pv->common->next_frame = hb_cond_init();
     pv->common->pts_count = 1;
     if ( job->frame_to_start || job->pts_to_start )
@@ -930,6 +930,13 @@ static int syncAudioWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
     hb_lock( pv->common->mutex );
     while ( !pv->common->start_found )
     {
+        if ( pv->common->audio_pts_thresh < 0 )
+        {
+            // I would initialize this in hb_sync_init, but 
+            // job->pts_to_start can be modified by reader 
+            // after hb_sync_init is called.
+            pv->common->audio_pts_thresh = job->pts_to_start;
+        }
         if ( buf->start < pv->common->audio_pts_thresh )
         {
             hb_buffer_close( &buf );