Discard decoded frames which differ from first decoded frame in stream.tags/n4.2
| @@ -55,6 +55,8 @@ Do not draw edges. | |||||
| @item psnr | @item psnr | ||||
| Set error[?] variables during encoding. | Set error[?] variables during encoding. | ||||
| @item truncated | @item truncated | ||||
| @item drop_changed | |||||
| Don't output frames whose parameters differ from first decoded frame in stream. | |||||
| @item ildct | @item ildct | ||||
| Use interlaced DCT. | Use interlaced DCT. | ||||
| @@ -859,6 +859,11 @@ typedef struct RcOverride{ | |||||
| * Use qpel MC. | * Use qpel MC. | ||||
| */ | */ | ||||
| #define AV_CODEC_FLAG_QPEL (1 << 4) | #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. | * Use internal 2pass ratecontrol in first pass mode. | ||||
| */ | */ | ||||
| @@ -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 | * AVERROR_EOF: the decoder has been fully flushed, and there will be | ||||
| * no more output frames | * no more output frames | ||||
| * AVERROR(EINVAL): codec not opened, or it is an encoder | * 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 | * other negative values: legitimate decoding errors | ||||
| */ | */ | ||||
| int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame); | int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame); | ||||
| @@ -740,7 +740,7 @@ static int apply_cropping(AVCodecContext *avctx, AVFrame *frame) | |||||
| int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) | int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) | ||||
| { | { | ||||
| AVCodecInternal *avci = avctx->internal; | AVCodecInternal *avci = avctx->internal; | ||||
| int ret; | |||||
| int ret, changed; | |||||
| av_frame_unref(frame); | av_frame_unref(frame); | ||||
| @@ -765,6 +765,51 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr | |||||
| avctx->frame_number++; | 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; | return 0; | ||||
| } | } | ||||
| @@ -218,6 +218,14 @@ typedef struct AVCodecInternal { | |||||
| /* to prevent infinite loop on errors when draining */ | /* to prevent infinite loop on errors when draining */ | ||||
| int nb_draining_errors; | 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; | } AVCodecInternal; | ||||
| struct AVCodecDefault { | struct AVCodecDefault { | ||||
| @@ -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"}, | {"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"}, | {"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"}, | {"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"}, | {"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"}, | {"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"}, | {"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"}, | ||||
| @@ -28,7 +28,7 @@ | |||||
| #include "libavutil/version.h" | #include "libavutil/version.h" | ||||
| #define LIBAVCODEC_VERSION_MAJOR 58 | #define LIBAVCODEC_VERSION_MAJOR 58 | ||||
| #define LIBAVCODEC_VERSION_MINOR 51 | |||||
| #define LIBAVCODEC_VERSION_MINOR 52 | |||||
| #define LIBAVCODEC_VERSION_MICRO 100 | #define LIBAVCODEC_VERSION_MICRO 100 | ||||
| #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | ||||