Add API function to trigger intra refresh
authorJason Garrett-Glaser <darkshikari@gmail.com>
Sat, 8 May 2010 19:07:13 +0000 (12:07 -0700)
committerJason Garrett-Glaser <darkshikari@gmail.com>
Mon, 17 May 2010 05:51:06 +0000 (22:51 -0700)
Useful for interactive applications where the encoder knows that packet loss has occurred on the client.
Full documentation is in x264.h.

common/common.h
encoder/encoder.c
x264.h

index 91d5030..f673648 100644 (file)
@@ -408,6 +408,8 @@ struct x264_t
     int             i_coded_fields_lookahead; /* Use separate counters for lookahead */
     int             i_cpb_delay_lookahead;
 
+    int             b_queued_intra_refresh;
+
     /* We use only one SPS and one PPS */
     x264_sps_t      sps_array[1];
     x264_sps_t      *sps;
index 7c5a64f..b4dbfad 100644 (file)
@@ -2131,6 +2131,12 @@ static int x264_threaded_slices_write( x264_t *h )
     return 0;
 }
 
+void x264_encoder_intra_refresh( x264_t *h )
+{
+    h = h->thread[h->i_thread_phase];
+    h->b_queued_intra_refresh = 1;
+}
+
 /****************************************************************************
  * x264_encoder_encode:
  *  XXX: i_poc   : is the poc of the current given picture
@@ -2380,6 +2386,7 @@ int     x264_encoder_encode( x264_t *h,
         if( IS_X264_TYPE_I( h->fenc->i_type ) )
         {
             h->fdec->i_frames_since_pir = 0;
+            h->b_queued_intra_refresh = 0;
             /* PIR is currently only supported with ref == 1, so any intra frame effectively refreshes
              * the whole frame and counts as an intra refresh. */
             h->fdec->f_pir_position = h->sps->i_mb_width;
@@ -2390,10 +2397,12 @@ int     x264_encoder_encode( x264_t *h,
             float increment = X264_MAX( ((float)h->sps->i_mb_width-1) / h->param.i_keyint_max, 1 );
             h->fdec->f_pir_position = h->fref0[0]->f_pir_position;
             h->fdec->i_frames_since_pir = h->fref0[0]->i_frames_since_pir + pocdiff;
-            if( h->fdec->i_frames_since_pir >= h->param.i_keyint_max )
+            if( h->fdec->i_frames_since_pir >= h->param.i_keyint_max ||
+                (h->b_queued_intra_refresh && h->fdec->f_pir_position + 0.5 >= h->sps->i_mb_width) )
             {
                 h->fdec->f_pir_position = 0;
                 h->fdec->i_frames_since_pir = 0;
+                h->b_queued_intra_refresh = 0;
                 h->fenc->b_keyframe = 1;
             }
             h->fdec->i_pir_start_col = h->fdec->f_pir_position+0.5;
diff --git a/x264.h b/x264.h
index 83f087e..f568dc5 100644 (file)
--- a/x264.h
+++ b/x264.h
@@ -35,7 +35,7 @@
 
 #include <stdarg.h>
 
-#define X264_BUILD 94
+#define X264_BUILD 95
 
 /* x264_t:
  *      opaque handler for encoder */
@@ -639,5 +639,13 @@ void    x264_encoder_close  ( x264_t * );
  *      return the number of currently delayed (buffered) frames
  *      this should be used at the end of the stream, to know when you have all the encoded frames. */
 int     x264_encoder_delayed_frames( x264_t * );
+/* x264_encoder_intra_refresh:
+ *      If an intra refresh is not in progress, begin one with the next P-frame.
+ *      If an intra refresh is in progress, begin one as soon as the current one finishes.
+ *      Requires that b_intra_refresh be set.
+ *      Useful for interactive streaming where the client can tell the server that packet loss has
+ *      occurred.  In this case, keyint can be set to an extremely high value so that intra refreshes
+ *      only occur when calling x264_encoder_intra_refresh. */
+void    x264_encoder_intra_refresh( x264_t * );
 
 #endif