| | 729 | |
|---|
| | 730 | |
|---|
| | 731 | static void optimize_video_pts( decoder_t *p_dec ) |
|---|
| | 732 | { |
|---|
| | 733 | picture_t * oldest_pict = NULL; |
|---|
| | 734 | picture_t * youngest_pict = NULL; |
|---|
| | 735 | int i; |
|---|
| | 736 | |
|---|
| | 737 | input_thread_t * p_input = p_dec->p_owner->p_input; |
|---|
| | 738 | vout_thread_t * p_vout = p_dec->p_owner->p_vout; |
|---|
| | 739 | input_thread_private_t * p_priv = p_input->p; |
|---|
| | 740 | |
|---|
| | 741 | if( !p_priv->pts_adjust.auto_adjust ) return; |
|---|
| | 742 | |
|---|
| | 743 | for( i = 0; i < I_RENDERPICTURES; i++ ) |
|---|
| | 744 | { |
|---|
| | 745 | picture_t * pic = PP_RENDERPICTURE[i]; |
|---|
| | 746 | if( pic->i_status != READY_PICTURE ) |
|---|
| | 747 | continue; |
|---|
| | 748 | |
|---|
| | 749 | if( !oldest_pict || pic->date < oldest_pict->date ) |
|---|
| | 750 | oldest_pict = pic; |
|---|
| | 751 | if( !youngest_pict || pic->date > youngest_pict->date ) |
|---|
| | 752 | youngest_pict = pic; |
|---|
| | 753 | } |
|---|
| | 754 | |
|---|
| | 755 | if( !youngest_pict || !oldest_pict ) |
|---|
| | 756 | return; |
|---|
| | 757 | |
|---|
| | 758 | /* Try to find if we can reduce the pts |
|---|
| | 759 | * This first draft is way to simple, and we can't say if the |
|---|
| | 760 | * algo will converge. It's also full of constants. |
|---|
| | 761 | * But this simple algo allows to reduce the latency |
|---|
| | 762 | * to the minimum. */ |
|---|
| | 763 | mtime_t buffer_size = youngest_pict->date - oldest_pict->date; |
|---|
| | 764 | int64_t pts_slide = 0; |
|---|
| | 765 | if( buffer_size < 10000 ) |
|---|
| | 766 | { |
|---|
| | 767 | if( p_priv->pts_adjust.i_num_faulty > 10 ) |
|---|
| | 768 | { |
|---|
| | 769 | pts_slide = __MAX(p_input->i_pts_delay *3 / 2, 10000); |
|---|
| | 770 | p_priv->pts_adjust.i_num_faulty = 0; |
|---|
| | 771 | } |
|---|
| | 772 | if( p_priv->pts_adjust.to_high ) |
|---|
| | 773 | { |
|---|
| | 774 | p_priv->pts_adjust.to_high = !p_priv->pts_adjust.to_high; |
|---|
| | 775 | p_priv->pts_adjust.i_num_faulty = 0; |
|---|
| | 776 | } |
|---|
| | 777 | p_priv->pts_adjust.i_num_faulty++; |
|---|
| | 778 | } |
|---|
| | 779 | else if( buffer_size > 100000 ) |
|---|
| | 780 | { |
|---|
| | 781 | if( p_priv->pts_adjust.i_num_faulty > 25 ) |
|---|
| | 782 | { |
|---|
| | 783 | pts_slide = -buffer_size/2; |
|---|
| | 784 | p_priv->pts_adjust.i_num_faulty = 0; |
|---|
| | 785 | } |
|---|
| | 786 | if( p_priv->pts_adjust.to_high ) |
|---|
| | 787 | { |
|---|
| | 788 | p_priv->pts_adjust.to_high = !p_priv->pts_adjust.to_high; |
|---|
| | 789 | p_priv->pts_adjust.i_num_faulty = 0; |
|---|
| | 790 | } |
|---|
| | 791 | p_priv->pts_adjust.i_num_faulty++; |
|---|
| | 792 | } |
|---|
| | 793 | if( pts_slide ) |
|---|
| | 794 | { |
|---|
| | 795 | mtime_t origi_delay = p_input->i_pts_delay; |
|---|
| | 796 | |
|---|
| | 797 | p_input->i_pts_delay += pts_slide; |
|---|
| | 798 | |
|---|
| | 799 | /* Don't play with the pts delay for more than -2<->3sec */ |
|---|
| | 800 | if( p_input->i_pts_delay < -2000000 ) |
|---|
| | 801 | p_input->i_pts_delay = -2000000; |
|---|
| | 802 | else if( p_input->i_pts_delay > 3000000 ) |
|---|
| | 803 | p_input->i_pts_delay = 3000000; |
|---|
| | 804 | pts_slide = p_input->i_pts_delay - origi_delay; |
|---|
| | 805 | |
|---|
| | 806 | msg_Dbg( p_input, "Sliding the pts by %dms pts delay at %dms picture buffer was %dms", |
|---|
| | 807 | (int)pts_slide/1000, (int)p_input->i_pts_delay/1000, (int)buffer_size/1000); |
|---|
| | 808 | |
|---|
| | 809 | vlc_mutex_lock( &p_vout->picture_lock ); |
|---|
| | 810 | /* Slide all the picture */ |
|---|
| | 811 | for( i = 0; i < I_RENDERPICTURES; i++ ) |
|---|
| | 812 | PP_RENDERPICTURE[i]->date += pts_slide; |
|---|
| | 813 | /* FIXME: slide aout/spu */ |
|---|
| | 814 | vlc_mutex_unlock( &p_vout->picture_lock ); |
|---|
| | 815 | |
|---|
| | 816 | } |
|---|
| | 817 | } |
|---|
| | 818 | |
|---|