[Android] [PATCH 1/4] android: try skipping frames automatically

Rafaël Carré funman at videolan.org
Mon Mar 5 00:04:56 CET 2012


From: tewilove <tewilove at gmail.com>

---
 modules/codec/avcodec/video.c |   55 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index 60ce6b6..b74a52f 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -84,6 +84,14 @@ struct decoder_sys_t
     /* how many decoded frames are late */
     int     i_late_frames;
     mtime_t i_late_frames_start;
+#ifdef __ANDROID__
+    int i_decode_called_count;
+    mtime_t i_decode_total_time;
+    mtime_t i_decode_average_time;
+    mtime_t i_decode_last_time;
+    mtime_t i_display_date_head;
+    int i_decode_may_suck;
+#endif
 
     /* for direct rendering */
     bool b_direct_rendering;
@@ -308,6 +316,14 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
             break;
     }
     p_sys->i_skip_idct = p_sys->p_context->skip_idct;
+#ifdef __ANDROID__
+    p_sys->i_decode_called_count = 0;
+    p_sys->i_decode_total_time = 0;
+    p_sys->i_decode_average_time = 0;
+    p_sys->i_decode_last_time = 0;
+    p_sys->i_display_date_head = 0;
+    p_sys->i_decode_may_suck = 0;
+#endif
 
     /* ***** ffmpeg direct rendering ***** */
     p_sys->b_direct_rendering = false;
@@ -512,6 +528,7 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         p_sys->i_late_frames = 0;
     }
 
+#ifndef __ANDROID__
     if( !p_dec->b_pace_control && (p_sys->i_late_frames > 0) &&
         (mdate() - p_sys->i_late_frames_start > INT64_C(5000000)) )
     {
@@ -573,6 +590,28 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
                                                   AVDISCARD_NONREF );
 #endif
     }
+#else
+    mtime_t i_time_now = mdate();
+    mtime_t i_time_adv = p_sys->i_display_date_head > 0 ? (p_sys->i_display_date_head - p_sys->i_decode_average_time - i_time_now) : 0;
+    p_sys->i_decode_may_suck = (i_time_adv < 0) ? (p_sys->i_decode_may_suck + 1) : 0;
+    bool b_skip_pred = (p_sys->i_decode_may_suck > 0);
+    bool b_skip_late = (p_sys->i_late_frames > 4);
+    bool b_no_skip_pred = (p_sys->i_decode_last_time < p_sys->i_decode_average_time);
+    bool b_no_skip_late = (i_time_now + p_sys->i_decode_average_time - p_sys->i_late_frames_start < 200000);
+    bool b_skip = ( (!p_dec->b_pace_control) && ((b_skip_pred && !b_no_skip_pred) || (b_skip_late && !b_no_skip_late)) );
+    p_context->skip_frame = b_skip ? AVDISCARD_NONREF : AVDISCARD_DEFAULT;
+    p_context->skip_idct = b_skip ? AVDISCARD_NONREF : AVDISCARD_DEFAULT;
+    p_context->skip_loop_filter = b_skip ? AVDISCARD_NONREF : AVDISCARD_DEFAULT;
+    p_context->flags2 = b_skip ? (p_context->flags2 | CODEC_FLAG2_FAST) : (p_context->flags2 & ~CODEC_FLAG2_FAST);
+    // if (b_skip)
+    //     msg_Dbg(p_dec, "frame skipping level set to AVDISCARD_NONREF");
+    if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
+        b_drawpicture = 1;
+    else
+        b_drawpicture = 0;
+    if( p_context->width <= 0 || p_context->height <= 0 )
+        b_null_size = true;
+#endif
 
     /*
      * Do the actual decoding now */
@@ -612,6 +651,9 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         p_block->i_pts =
         p_block->i_dts = VLC_TS_INVALID;
 
+#ifdef __ANDROID__
+        mtime_t i_decode_start = mdate();
+#endif
         post_mt( p_sys );
 
         av_init_packet( &pkt );
@@ -632,6 +674,15 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         }
         wait_mt( p_sys );
 
+#ifdef __ANDROID__
+        mtime_t i_decode_end = mdate();
+        mtime_t i_decode_time = i_decode_end - i_decode_start;
+        p_sys->i_decode_called_count += 1;
+        p_sys->i_decode_total_time += i_decode_time;
+        p_sys->i_decode_average_time = (p_sys->i_decode_total_time / p_sys->i_decode_called_count);
+        p_sys->i_decode_last_time = i_decode_time;
+#endif
+
         if( p_sys->b_flush )
             p_sys->b_first_frame = true;
 
@@ -732,6 +783,10 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
             i_display_date = decoder_GetDisplayDate( p_dec, i_pts );
 
+#ifdef __ANDROID__
+        p_sys->i_display_date_head = i_display_date;
+#endif
+
         if( i_display_date > 0 && i_display_date <= mdate() )
         {
             p_sys->i_late_frames++;
-- 
1.7.9


More information about the Android mailing list