diff options
author | Gyan Doshi <ffmpeg@gyani.pro> | 2019-04-14 22:12:25 +0530 |
---|---|---|
committer | Gyan Doshi <ffmpeg@gyani.pro> | 2019-04-20 10:38:01 +0530 |
commit | 3153a6502a28b20a0da822daf32bcd8f7c90d721 (patch) | |
tree | f3673539f54af82ab363d813eb42cd72048105e8 | |
parent | d93e44332f1bd2be90eb637268385a5acd8f6c10 (diff) | |
download | ffmpeg-streaming-3153a6502a28b20a0da822daf32bcd8f7c90d721.zip ffmpeg-streaming-3153a6502a28b20a0da822daf32bcd8f7c90d721.tar.gz |
avcodec: add AV_CODEC_FLAG_DROPCHANGED to flags
Discard decoded frames which differ from first decoded frame in stream.
-rw-r--r-- | doc/codecs.texi | 2 | ||||
-rw-r--r-- | libavcodec/avcodec.h | 8 | ||||
-rw-r--r-- | libavcodec/decode.c | 47 | ||||
-rw-r--r-- | libavcodec/internal.h | 8 | ||||
-rw-r--r-- | libavcodec/options_table.h | 1 | ||||
-rw-r--r-- | libavcodec/version.h | 2 |
6 files changed, 66 insertions, 2 deletions
diff --git a/doc/codecs.texi b/doc/codecs.texi index 572e561..0baafee 100644 --- a/doc/codecs.texi +++ b/doc/codecs.texi @@ -55,6 +55,8 @@ Do not draw edges. @item psnr Set error[?] variables during encoding. @item truncated +@item drop_changed +Don't output frames whose parameters differ from first decoded frame in stream. @item ildct Use interlaced DCT. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 9e37466..b749946 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -860,6 +860,11 @@ typedef struct RcOverride{ */ #define AV_CODEC_FLAG_QPEL (1 << 4) /** + * Don't output frames whose parameters differ from first + * decoded frame in stream. + */ +#define AV_CODEC_FLAG_DROPCHANGED (1 << 5) +/** * Use internal 2pass ratecontrol in first pass mode. */ #define AV_CODEC_FLAG_PASS1 (1 << 9) @@ -4918,6 +4923,9 @@ int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt); * AVERROR_EOF: the decoder has been fully flushed, and there will be * no more output frames * AVERROR(EINVAL): codec not opened, or it is an encoder + * AVERROR_INPUT_CHANGED: current decoded frame has changed parameters + * with respect to first decoded frame. Applicable + * when flag AV_CODEC_FLAG_DROPCHANGED is set. * other negative values: legitimate decoding errors */ int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame); diff --git a/libavcodec/decode.c b/libavcodec/decode.c index a32ff2f..6c31166 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -740,7 +740,7 @@ static int apply_cropping(AVCodecContext *avctx, AVFrame *frame) int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) { AVCodecInternal *avci = avctx->internal; - int ret; + int ret, changed; av_frame_unref(frame); @@ -765,6 +765,51 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr avctx->frame_number++; + if (avctx->flags & AV_CODEC_FLAG_DROPCHANGED) { + + if (avctx->frame_number == 1) { + avci->initial_format = frame->format; + switch(avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: + avci->initial_width = frame->width; + avci->initial_height = frame->height; + break; + case AVMEDIA_TYPE_AUDIO: + avci->initial_sample_rate = frame->sample_rate ? frame->sample_rate : + avctx->sample_rate; + avci->initial_channels = frame->channels; + avci->initial_channel_layout = frame->channel_layout; + break; + } + } + + if (avctx->frame_number > 1) { + changed = avci->initial_format != frame->format; + + switch(avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: + changed |= avci->initial_width != frame->width || + avci->initial_height != frame->height; + break; + case AVMEDIA_TYPE_AUDIO: + changed |= avci->initial_sample_rate != frame->sample_rate || + avci->initial_sample_rate != avctx->sample_rate || + avci->initial_channels != frame->channels || + avci->initial_channel_layout != frame->channel_layout; + break; + } + + if (changed) { + avci->changed_frames_dropped++; + av_log(avctx, AV_LOG_INFO, "dropped changed frame #%d pts %"PRId64 + " drop count: %d \n", + avctx->frame_number, frame->pts, + avci->changed_frames_dropped); + av_frame_unref(frame); + return AVERROR_INPUT_CHANGED; + } + } + } return 0; } diff --git a/libavcodec/internal.h b/libavcodec/internal.h index f2e6f00..5096ffa 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -218,6 +218,14 @@ typedef struct AVCodecInternal { /* to prevent infinite loop on errors when draining */ int nb_draining_errors; + + /* used when avctx flag AV_CODEC_FLAG_DROPCHANGED is set */ + int changed_frames_dropped; + int initial_format; + int initial_width, initial_height; + int initial_sample_rate; + int initial_channels; + uint64_t initial_channel_layout; } AVCodecInternal; struct AVCodecDefault { diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index a3235bc..4a266ec 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -67,6 +67,7 @@ static const AVOption avcodec_options[] = { {"ilme", "interlaced motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, "flags"}, {"cgop", "closed GOP", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"}, {"output_corrupt", "Output even potentially corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_OUTPUT_CORRUPT }, INT_MIN, INT_MAX, V|D, "flags"}, +{"drop_changed", "Drop frames whose parameters differ from first decoded frame", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_DROPCHANGED }, INT_MIN, INT_MAX, A|V|D, "flags"}, {"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, V|A|E|D, "flags2"}, {"fast", "allow non-spec-compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"}, {"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"}, diff --git a/libavcodec/version.h b/libavcodec/version.h index 1b60202..195e21b 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 51 +#define LIBAVCODEC_VERSION_MINOR 52 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ |