diff --git a/libavcodec/adxenc.c b/libavcodec/adxenc.c index 153c91b852..6e12a58b16 100644 --- a/libavcodec/adxenc.c +++ b/libavcodec/adxenc.c @@ -183,8 +183,6 @@ static int adx_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, dst += BLOCK_SIZE; } - avpkt->pts = frame->pts; - avpkt->duration = frame->nb_samples; *got_packet_ptr = 1; return 0; } @@ -200,4 +198,5 @@ const FFCodec ff_adpcm_adx_encoder = { FF_CODEC_ENCODE_CB(adx_encode_frame), .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_EOF_FLUSH, }; diff --git a/libavcodec/codec_internal.h b/libavcodec/codec_internal.h index e3b77e6dea..130a7dc3cd 100644 --- a/libavcodec/codec_internal.h +++ b/libavcodec/codec_internal.h @@ -80,6 +80,14 @@ * Codec supports embedded ICC profiles (AV_FRAME_DATA_ICC_PROFILE). */ #define FF_CODEC_CAP_ICC_PROFILES (1 << 9) +/** + * The encoder has AV_CODEC_CAP_DELAY set, but does not actually have delay - it + * only wants to be flushed at the end to update some context variables (e.g. + * 2pass stats) or produce a trailing packet. Besides that it immediately + * produces exactly one output packet per each input frame, just as no-delay + * encoders do. + */ +#define FF_CODEC_CAP_EOF_FLUSH (1 << 10) /** * FFCodec.codec_tags termination value diff --git a/libavcodec/encode.c b/libavcodec/encode.c index fbe2c97cd6..e0b3e43840 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -211,7 +211,8 @@ int ff_encode_encode_cb(AVCodecContext *avctx, AVPacket *avpkt, // set the timestamps for the simple no-delay case // encoders with delay have to set the timestamps themselves - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || + (frame && (codec->caps_internal & FF_CODEC_CAP_EOF_FLUSH))) { if (avpkt->pts == AV_NOPTS_VALUE) avpkt->pts = frame->pts; @@ -225,7 +226,8 @@ int ff_encode_encode_cb(AVCodecContext *avctx, AVPacket *avpkt, // dts equals pts unless there is reordering // there can be no reordering if there is no encoder delay if (!(avctx->codec_descriptor->props & AV_CODEC_PROP_REORDER) || - !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) + !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || + (codec->caps_internal & FF_CODEC_CAP_EOF_FLUSH)) avpkt->dts = avpkt->pts; } else { unref: diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 0237ac48eb..6649ec7e88 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -1231,8 +1231,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, f->picture_number++; pkt->size = buf_p - pkt->data; - pkt->pts = - pkt->dts = pict->pts; pkt->flags |= AV_PKT_FLAG_KEY * f->key_frame; *got_packet = 1; @@ -1301,5 +1299,5 @@ const FFCodec ff_ffv1_encoder = { }, .p.priv_class = &ffv1_class, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_EOF_FLUSH, }; diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c index 8aacc93e28..9a9835dfa6 100644 --- a/libavcodec/flacenc.c +++ b/libavcodec/flacenc.c @@ -1690,10 +1690,7 @@ static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (out_bytes < s->min_framesize) s->min_framesize = out_bytes; - avpkt->pts = frame->pts; - avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples); - - s->next_pts = avpkt->pts + avpkt->duration; + s->next_pts = frame->pts + ff_samples_to_time_base(avctx, frame->nb_samples); av_shrink_packet(avpkt, out_bytes); @@ -1766,5 +1763,5 @@ const FFCodec ff_flac_encoder = { AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE }, .p.priv_class = &flac_encoder_class, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_EOF_FLUSH, }; diff --git a/libavcodec/tests/avcodec.c b/libavcodec/tests/avcodec.c index 3288a85f64..4c1730425d 100644 --- a/libavcodec/tests/avcodec.c +++ b/libavcodec/tests/avcodec.c @@ -158,6 +158,10 @@ int main(void){ if (codec->capabilities & AV_CODEC_CAP_FRAME_THREADS && codec->capabilities & AV_CODEC_CAP_DELAY) ERR("Frame-threaded encoder %s claims to have delay\n"); + + if (codec2->caps_internal & FF_CODEC_CAP_EOF_FLUSH && + !(codec->capabilities & AV_CODEC_CAP_DELAY)) + ERR("EOF_FLUSH encoder %s is not marked as having delay\n"); } else { if ((codec->type == AVMEDIA_TYPE_SUBTITLE) != (codec2->cb_type == FF_CODEC_CB_TYPE_DECODE_SUB)) ERR("Subtitle decoder %s does not implement decode_sub callback\n");