diff --git a/ffplay.c b/ffplay.c index e58f20dcaa..33d263ba5b 100644 --- a/ffplay.c +++ b/ffplay.c @@ -194,6 +194,9 @@ static int workaround_bugs = 1; static int fast = 0; static int lowres = 0; static int idct = FF_IDCT_AUTO; +static enum AVDiscard skip_frame= AVDISCARD_DEFAULT; +static enum AVDiscard skip_idct= AVDISCARD_DEFAULT; +static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT; /* current context */ static int is_full_screen; @@ -1190,6 +1193,9 @@ static int stream_component_open(VideoState *is, int stream_index) if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE; enc->idct_algo= idct; if(fast) enc->flags2 |= CODEC_FLAG2_FAST; + enc->skip_frame= skip_frame; + enc->skip_idct= skip_idct; + enc->skip_loop_filter= skip_loop_filter; if (!codec || avcodec_open(enc, codec) < 0) return -1; @@ -1863,6 +1869,9 @@ const OptionDef options[] = { { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" }, { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" }, { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" }, + { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" }, + { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" }, + { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" }, { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo", "algo" }, #ifdef CONFIG_NETWORK { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" }, diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 9656926c05..8b113cd4d0 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -17,7 +17,8 @@ extern "C" { #define FFMPEG_VERSION_INT 0x000409 #define FFMPEG_VERSION "CVS" -#define LIBAVCODEC_BUILD 4757 +#define LIBAVCODEC_BUILD 4758 + #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT #define LIBAVCODEC_VERSION FFMPEG_VERSION @@ -284,6 +285,16 @@ enum AVRounding { AV_ROUND_NEAR_INF = 5, ///< round to nearest and halfway cases away from zero }; +enum AVDiscard{ +//we leave some space between them for extensions (drop some keyframes for intra only or drop just some bidir frames) + AVDISCARD_NONE =-16, ///< discard nothing + AVDISCARD_DEFAULT= 0, ///< discard useless packets like 0 size packets in avi + AVDISCARD_NONREF = 8, ///< discard all non reference + AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames + AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes + AVDISCARD_ALL = 48, ///< discard all +}; + typedef struct RcOverride{ int start_frame; int end_frame; @@ -858,6 +869,7 @@ typedef struct AVCodecContext { /** * hurry up amount. + * deprecated in favor of skip_idct and skip_frame * - encoding: unused * - decoding: set by user. 1-> skip b frames, 2-> skip idct/dequant too, 5-> skip everything except header */ @@ -1807,6 +1819,27 @@ typedef struct AVCodecContext { * - decoding: unused */ int me_penalty_compensation; + + /** + * + * - encoding: unused + * - decoding: set by user. + */ + enum AVDiscard skip_loop_filter; + + /** + * + * - encoding: unused + * - decoding: set by user. + */ + enum AVDiscard skip_idct; + + /** + * + * - encoding: unused + * - decoding: set by user. + */ + enum AVDiscard skip_frame; } AVCodecContext; diff --git a/libavcodec/h261.c b/libavcodec/h261.c index f9e148455c..a823cc39bc 100644 --- a/libavcodec/h261.c +++ b/libavcodec/h261.c @@ -970,6 +970,10 @@ retry: /* skip everything if we are in a hurry>=5 */ if(avctx->hurry_up>=5) return get_consumed_bytes(s, buf_size); + if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE) + ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE) + || avctx->skip_frame >= AVDISCARD_ALL) + return get_consumed_bytes(s, buf_size); if(MPV_frame_start(s, avctx) < 0) return -1; diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index ba105564f2..b51ce5f0c4 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -673,6 +673,10 @@ retry: if(s->last_picture_ptr==NULL && (s->pict_type==B_TYPE || s->dropable)) return get_consumed_bytes(s, buf_size); /* skip b frames if we are in a hurry */ if(avctx->hurry_up && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size); + if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE) + || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE) + || avctx->skip_frame >= AVDISCARD_ALL) + return get_consumed_bytes(s, buf_size); /* skip everything if we are in a hurry>=5 */ if(avctx->hurry_up>=5) return get_consumed_bytes(s, buf_size); diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 741c0503c6..3e318bddeb 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -4349,6 +4349,11 @@ static int decode_slice_header(H264Context *h){ h->slice_beta_offset = get_se_golomb(&s->gb) << 1; } } + if( s->avctx->skip_loop_filter >= AVDISCARD_ALL + ||(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY && h->slice_type != I_TYPE) + ||(s->avctx->skip_loop_filter >= AVDISCARD_BIDIR && h->slice_type == B_TYPE) + ||(s->avctx->skip_loop_filter >= AVDISCARD_NONREF && h->nal_ref_idc == 0)) + h->deblocking_filter= 0; #if 0 //FMO if( h->pps.num_slice_groups > 1 && h->pps.mb_slice_group_map_type >= 3 && h->pps.mb_slice_group_map_type <= 5) @@ -7245,7 +7250,8 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){ buf_index += consumed; - if( s->hurry_up == 1 && h->nal_ref_idc == 0 ) + if( (s->hurry_up == 1 && h->nal_ref_idc == 0) + ||(avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0)) continue; switch(h->nal_unit_type){ @@ -7261,7 +7267,7 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){ av_log(h->s.avctx, AV_LOG_ERROR, "decode_slice_header error\n"); break; } - if(h->redundant_pic_count==0 && s->hurry_up < 5 ) + if(h->redundant_pic_count==0 && s->hurry_up < 5 && avctx->skip_frame < AVDISCARD_ALL) decode_slice(h); break; case NAL_DPA: @@ -7282,7 +7288,8 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){ init_get_bits(&h->inter_gb, ptr, bit_length); h->inter_gb_ptr= &h->inter_gb; - if(h->redundant_pic_count==0 && h->intra_gb_ptr && s->data_partitioning && s->hurry_up < 5 ) + if(h->redundant_pic_count==0 && h->intra_gb_ptr && s->data_partitioning + && s->hurry_up < 5 && avctx->skip_frame < AVDISCARD_ALL) decode_slice(h); break; case NAL_SEI: diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 33fc2faa75..a609ee34e5 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -3086,7 +3086,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, /* find start next code */ start_code = find_start_code(&buf_ptr, buf_end); if (start_code < 0){ - if(s2->pict_type != B_TYPE || avctx->hurry_up==0){ + if(s2->pict_type != B_TYPE || avctx->skip_frame <= AVDISCARD_DEFAULT){ if(avctx->thread_count > 1){ int i; @@ -3146,6 +3146,10 @@ static int mpeg_decode_frame(AVCodecContext *avctx, } /* skip b frames if we are in a hurry */ if(avctx->hurry_up && s2->pict_type==B_TYPE) break; + if( (avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type==B_TYPE) + ||(avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type!=I_TYPE) + || avctx->skip_frame >= AVDISCARD_ALL) + break; /* skip everything if we are in a hurry>=5 */ if(avctx->hurry_up>=5) break; diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index b767c7d554..a6017136e1 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -3777,7 +3777,13 @@ static always_inline void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM bloc } /* skip dequant / idct if we are really late ;) */ - if(s->hurry_up>1) return; + if(s->hurry_up>1) goto skip_idct; + if(s->avctx->skip_idct){ + if( (s->avctx->skip_idct >= AVDISCARD_NONREF && s->pict_type == B_TYPE) + ||(s->avctx->skip_idct >= AVDISCARD_NONKEY && s->pict_type != I_TYPE) + || s->avctx->skip_idct >= AVDISCARD_ALL) + goto skip_idct; + } /* add dct residue */ if(s->encoding || !( s->h263_msmpeg4 || s->codec_id==CODEC_ID_MPEG1VIDEO || s->codec_id==CODEC_ID_MPEG2VIDEO @@ -3863,6 +3869,7 @@ static always_inline void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM bloc }//gray } } +skip_idct: if(!readable){ s->dsp.put_pixels_tab[0][0](s->dest[0], dest_y , linesize,16); s->dsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[1], dest_cb, uvlinesize,16 >> s->chroma_y_shift); diff --git a/libavcodec/svq1.c b/libavcodec/svq1.c index 068dd51d37..e59f1c731b 100644 --- a/libavcodec/svq1.c +++ b/libavcodec/svq1.c @@ -748,6 +748,10 @@ static int svq1_decode_frame(AVCodecContext *avctx, if(s->pict_type==B_TYPE && s->last_picture_ptr==NULL) return buf_size; if(avctx->hurry_up && s->pict_type==B_TYPE) return buf_size; + if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE) + ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE) + || avctx->skip_frame >= AVDISCARD_ALL) + return buf_size; if(MPV_frame_start(s, avctx) < 0) return -1; diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 547679bf1c..f0f995acfa 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -896,6 +896,10 @@ static int svq3_decode_frame (AVCodecContext *avctx, if (avctx->hurry_up && s->pict_type == B_TYPE) return 0; /* skip everything if we are in a hurry >= 5 */ if (avctx->hurry_up >= 5) return 0; + if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE) + ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE) + || avctx->skip_frame >= AVDISCARD_ALL) + return 0; if (s->next_p_frame_damaged) { if (s->pict_type == B_TYPE) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 0473595ac3..6f05f19b7b 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -213,15 +213,6 @@ typedef struct AVIndexEntry { int min_distance; /* min distance between this and the previous keyframe, used to avoid unneeded searching */ } AVIndexEntry; -enum AVDiscard{ -//we leave some space between them for extensions (drop some keyframes for intra only or drop just some bidir frames) - AVDISCARD_NONE =-16, ///< discard nothing - AVDISCARD_DEFAULT= 0, ///< discard useless packets like 0 size packets in avi - AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames - AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes - AVDISCARD_ALL = 48, ///< discard all -}; - typedef struct AVStream { int index; /* stream index in AVFormatContext */ int id; /* format specific stream id */