Commit 9d20efbb authored by Jean-Paul Saman's avatar Jean-Paul Saman

Implement framedropping algorithm using avcontext.skip_frames and added two new options:

- ffmpeg-skip-frames    values: -1=None, 0=Default, 1=B-frames, 2=P-frames, 3=B+P frames, 4=all frames
- ffmpeg-skip-idct	values: -1=None, 0=Default, 1=B-frames, 2=P-frames, 3=B+P frames, 4=all frame)
parent 41303be0
...@@ -110,6 +110,12 @@ vlc_module_begin(); ...@@ -110,6 +110,12 @@ vlc_module_begin();
VLC_FALSE ); VLC_FALSE );
add_bool( "ffmpeg-hurry-up", 0, NULL, HURRYUP_TEXT, HURRYUP_LONGTEXT, add_bool( "ffmpeg-hurry-up", 0, NULL, HURRYUP_TEXT, HURRYUP_LONGTEXT,
VLC_FALSE ); VLC_FALSE );
add_integer( "ffmpeg-skip-frame", 0, NULL, SKIP_FRAME_TEXT,
SKIP_FRAME_LONGTEXT, VLC_TRUE );
change_integer_range( -1, 4 );
add_integer( "ffmpeg-skip-idct", 0, NULL, SKIP_IDCT_TEXT,
SKIP_IDCT_LONGTEXT, VLC_TRUE );
change_integer_range( -1, 4 );
add_integer ( "ffmpeg-vismv", 0, NULL, VISMV_TEXT, VISMV_LONGTEXT, add_integer ( "ffmpeg-vismv", 0, NULL, VISMV_TEXT, VISMV_LONGTEXT,
VLC_TRUE ); VLC_TRUE );
add_integer ( "ffmpeg-lowres", 0, NULL, LOWRES_TEXT, LOWRES_LONGTEXT, add_integer ( "ffmpeg-lowres", 0, NULL, LOWRES_TEXT, LOWRES_LONGTEXT,
...@@ -305,6 +311,10 @@ static int OpenDecoder( vlc_object_t *p_this ) ...@@ -305,6 +311,10 @@ static int OpenDecoder( vlc_object_t *p_this )
{ {
p_context->dsp_mask |= FF_MM_SSE2; p_context->dsp_mask |= FF_MM_SSE2;
} }
if( !(i_cpu & CPU_CAPABILITY_IWMMXT) )
{
p_context->dsp_mask |= FF_MM_IWMMXT;
}
p_dec->b_need_packetized = VLC_TRUE; p_dec->b_need_packetized = VLC_TRUE;
switch( i_cat ) switch( i_cat )
......
...@@ -116,6 +116,16 @@ void E_(ClosePostproc)( decoder_t *, void * ); ...@@ -116,6 +116,16 @@ void E_(ClosePostproc)( decoder_t *, void * );
"when there is not enough time. It's useful with low CPU power " \ "when there is not enough time. It's useful with low CPU power " \
"but it can produce distorted pictures.") "but it can produce distorted pictures.")
#define SKIP_FRAME_TEXT N_("Skip frame (default=0)")
#define SKIP_FRAME_LONGTEXT N_( \
"Force skipping of frames to speed up decoding " \
"(-1=None, 0=Default, 1=B-frames, 2=P-frames, 3=B+P frames, 4=all frames)." )
#define SKIP_IDCT_TEXT N_("Skip idct (default=0)")
#define SKIP_IDCT_LONGTEXT N_( \
"Force skipping of idct to speed up decoding for frame types" \
"(-1=None, 0=Default, 1=B-frames, 2=P-frames, 3=B+P frames, 4=all frames)." )
#define PP_Q_TEXT N_("Post processing quality") #define PP_Q_TEXT N_("Post processing quality")
#define PP_Q_LONGTEXT N_( \ #define PP_Q_LONGTEXT N_( \
"Quality of post processing. Valid range is 0 to 6\n" \ "Quality of post processing. Valid range is 0 to 6\n" \
...@@ -305,7 +315,7 @@ N_("<filterName>[:<option>[:<option>...]][[,|/][-]<filterName>[:<option>...]]... ...@@ -305,7 +315,7 @@ N_("<filterName>[:<option>[:<option>...]][[,|/][-]<filterName>[:<option>...]]...
#define FFMPEG_COMMON_MEMBERS \ #define FFMPEG_COMMON_MEMBERS \
int i_cat; \ int i_cat; \
int i_codec_id; \ int i_codec_id; \
char *psz_namecodec; \ const char *psz_namecodec; \
AVCodecContext *p_context; \ AVCodecContext *p_context; \
AVCodec *p_codec; AVCodec *p_codec;
...@@ -56,7 +56,6 @@ struct decoder_sys_t ...@@ -56,7 +56,6 @@ struct decoder_sys_t
/* for frame skipping algo */ /* for frame skipping algo */
int b_hurry_up; int b_hurry_up;
int i_frame_skip;
/* how many decoded frames are late */ /* how many decoded frames are late */
int i_late_frames; int i_late_frames;
...@@ -227,6 +226,7 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context, ...@@ -227,6 +226,7 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
msg_Err( p_dec, "out of memory" ); msg_Err( p_dec, "out of memory" );
return VLC_ENOMEM; return VLC_ENOMEM;
} }
memset( p_sys, 0, sizeof(decoder_sys_t) );
p_dec->p_sys->p_context = p_context; p_dec->p_sys->p_context = p_context;
p_dec->p_sys->p_codec = p_codec; p_dec->p_sys->p_codec = p_codec;
...@@ -271,6 +271,54 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context, ...@@ -271,6 +271,54 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
var_Get( p_dec, "ffmpeg-hurry-up", &val ); var_Get( p_dec, "ffmpeg-hurry-up", &val );
p_sys->b_hurry_up = val.b_bool; p_sys->b_hurry_up = val.b_bool;
var_Create( p_dec, "ffmpeg-skip-frame", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Get( p_dec, "ffmpeg-skip-frame", &val );
switch( val.i_int )
{
case -1:
p_sys->p_context->skip_frame = AVDISCARD_NONE;
break;
case 0:
p_sys->p_context->skip_frame = AVDISCARD_DEFAULT;
break;
case 1:
p_sys->p_context->skip_frame = AVDISCARD_BIDIR;
break;
case 2:
p_sys->p_context->skip_frame = AVDISCARD_NONKEY;
break;
case 3:
p_sys->p_context->skip_frame = AVDISCARD_ALL;
break;
default:
p_sys->p_context->skip_frame = AVDISCARD_NONE;
break;
}
var_Create( p_dec, "ffmpeg-skip-idct", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Get( p_dec, "ffmpeg-skip-idct", &val );
switch( val.i_int )
{
case -1:
p_sys->p_context->skip_idct = AVDISCARD_NONE;
break;
case 0:
p_sys->p_context->skip_idct = AVDISCARD_DEFAULT;
break;
case 1:
p_sys->p_context->skip_idct = AVDISCARD_BIDIR;
break;
case 2:
p_sys->p_context->skip_idct = AVDISCARD_NONKEY;
break;
case 3:
p_sys->p_context->skip_idct = AVDISCARD_ALL;
break;
default:
p_sys->p_context->skip_idct = AVDISCARD_NONE;
break;
}
/* ***** ffmpeg direct rendering ***** */ /* ***** ffmpeg direct rendering ***** */
p_sys->b_direct_rendering = 0; p_sys->b_direct_rendering = 0;
var_Create( p_dec, "ffmpeg-dr", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_dec, "ffmpeg-dr", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
...@@ -385,8 +433,8 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block ) ...@@ -385,8 +433,8 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
p_sys->i_late_frames = 0; p_sys->i_late_frames = 0;
} }
if( !p_dec->b_pace_control && p_sys->i_late_frames > 0 && if( !p_dec->b_pace_control && (p_sys->i_late_frames > 0) &&
mdate() - p_sys->i_late_frames_start > I64C(5000000) ) (mdate() - p_sys->i_late_frames_start > I64C(5000000)) )
{ {
if( p_sys->i_pts ) if( p_sys->i_pts )
{ {
...@@ -411,18 +459,19 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block ) ...@@ -411,18 +459,19 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
/* TODO implement it in a better way */ /* TODO implement it in a better way */
/* A good idea could be to decode all I pictures and see for the other */ /* A good idea could be to decode all I pictures and see for the other */
if( !p_dec->b_pace_control && if( !p_dec->b_pace_control &&
p_sys->b_hurry_up && p_sys->i_late_frames > 4 ) p_sys->b_hurry_up &&
(p_sys->i_late_frames > 4) )
{ {
b_drawpicture = 0; b_drawpicture = 0;
if( p_sys->i_late_frames < 8 ) if( p_sys->i_late_frames < 8 )
{ {
p_sys->p_context->hurry_up = 2; p_sys->p_context->skip_frame = AVDISCARD_BIDIR;
} }
else else
{ {
/* picture too late, won't decode /* picture too late, won't decode
* but break picture until a new I, and for mpeg4 ...*/ * but break picture until a new I, and for mpeg4 ...*/
p_sys->p_context->skip_frame = AVDISCARD_NONKEY;
p_sys->i_late_frames--; /* needed else it will never be decrease */ p_sys->i_late_frames--; /* needed else it will never be decrease */
block_Release( p_block ); block_Release( p_block );
p_sys->i_buffer = 0; p_sys->i_buffer = 0;
...@@ -431,17 +480,18 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block ) ...@@ -431,17 +480,18 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
} }
else else
{ {
p_sys->p_context->hurry_up = 0; if( p_sys->b_hurry_up )
p_sys->p_context->skip_frame = AVDISCARD_DEFAULT;
if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) ) if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
b_drawpicture = 1; b_drawpicture = 1;
else else
b_drawpicture = 0; b_drawpicture = 0;
} }
if( p_sys->p_context->width <= 0 || p_sys->p_context->height <= 0 ) if( p_sys->p_context->width <= 0 || p_sys->p_context->height <= 0 )
{ {
p_sys->p_context->hurry_up = 5; if( p_sys->b_hurry_up )
p_sys->p_context->skip_frame = AVDISCARD_ALL;
b_null_size = VLC_TRUE; b_null_size = VLC_TRUE;
} }
...@@ -488,7 +538,8 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block ) ...@@ -488,7 +538,8 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
{ {
/* Reparse it to not drop the I frame */ /* Reparse it to not drop the I frame */
b_null_size = VLC_FALSE; b_null_size = VLC_FALSE;
p_sys->p_context->hurry_up = 0; if( p_sys->b_hurry_up )
p_sys->p_context->skip_frame = AVDISCARD_DEFAULT;
i_used = avcodec_decode_video( p_sys->p_context, p_sys->p_ff_pic, i_used = avcodec_decode_video( p_sys->p_context, p_sys->p_ff_pic,
&b_gotpicture, &b_gotpicture,
(uint8_t*)p_sys->p_buffer, p_sys->i_buffer ); (uint8_t*)p_sys->p_buffer, p_sys->i_buffer );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment