lavc: add a private cap for fake-delay encoders
Some encoders (ffv1, flac, adx) are marked with AV_CODEC_CAP_DELAY onky in order to be flushed at the end, otherwise they behave as no-delay encoders. Add a capability to mark these encoders. Use it for setting pts generically.
This commit is contained in:
@ -183,8 +183,6 @@ static int adx_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
|||||||
dst += BLOCK_SIZE;
|
dst += BLOCK_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
avpkt->pts = frame->pts;
|
|
||||||
avpkt->duration = frame->nb_samples;
|
|
||||||
*got_packet_ptr = 1;
|
*got_packet_ptr = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -200,4 +198,5 @@ const FFCodec ff_adpcm_adx_encoder = {
|
|||||||
FF_CODEC_ENCODE_CB(adx_encode_frame),
|
FF_CODEC_ENCODE_CB(adx_encode_frame),
|
||||||
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
|
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
|
||||||
AV_SAMPLE_FMT_NONE },
|
AV_SAMPLE_FMT_NONE },
|
||||||
|
.caps_internal = FF_CODEC_CAP_EOF_FLUSH,
|
||||||
};
|
};
|
||||||
|
@ -80,6 +80,14 @@
|
|||||||
* Codec supports embedded ICC profiles (AV_FRAME_DATA_ICC_PROFILE).
|
* Codec supports embedded ICC profiles (AV_FRAME_DATA_ICC_PROFILE).
|
||||||
*/
|
*/
|
||||||
#define FF_CODEC_CAP_ICC_PROFILES (1 << 9)
|
#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
|
* FFCodec.codec_tags termination value
|
||||||
|
@ -211,7 +211,8 @@ int ff_encode_encode_cb(AVCodecContext *avctx, AVPacket *avpkt,
|
|||||||
|
|
||||||
// set the timestamps for the simple no-delay case
|
// set the timestamps for the simple no-delay case
|
||||||
// encoders with delay have to set the timestamps themselves
|
// 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)
|
if (avpkt->pts == AV_NOPTS_VALUE)
|
||||||
avpkt->pts = frame->pts;
|
avpkt->pts = frame->pts;
|
||||||
|
|
||||||
@ -225,7 +226,8 @@ int ff_encode_encode_cb(AVCodecContext *avctx, AVPacket *avpkt,
|
|||||||
// dts equals pts unless there is reordering
|
// dts equals pts unless there is reordering
|
||||||
// there can be no reordering if there is no encoder delay
|
// there can be no reordering if there is no encoder delay
|
||||||
if (!(avctx->codec_descriptor->props & AV_CODEC_PROP_REORDER) ||
|
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;
|
avpkt->dts = avpkt->pts;
|
||||||
} else {
|
} else {
|
||||||
unref:
|
unref:
|
||||||
|
@ -1231,8 +1231,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
|
|
||||||
f->picture_number++;
|
f->picture_number++;
|
||||||
pkt->size = buf_p - pkt->data;
|
pkt->size = buf_p - pkt->data;
|
||||||
pkt->pts =
|
|
||||||
pkt->dts = pict->pts;
|
|
||||||
pkt->flags |= AV_PKT_FLAG_KEY * f->key_frame;
|
pkt->flags |= AV_PKT_FLAG_KEY * f->key_frame;
|
||||||
*got_packet = 1;
|
*got_packet = 1;
|
||||||
|
|
||||||
@ -1301,5 +1299,5 @@ const FFCodec ff_ffv1_encoder = {
|
|||||||
|
|
||||||
},
|
},
|
||||||
.p.priv_class = &ffv1_class,
|
.p.priv_class = &ffv1_class,
|
||||||
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
|
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_EOF_FLUSH,
|
||||||
};
|
};
|
||||||
|
@ -1690,10 +1690,7 @@ static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
|||||||
if (out_bytes < s->min_framesize)
|
if (out_bytes < s->min_framesize)
|
||||||
s->min_framesize = out_bytes;
|
s->min_framesize = out_bytes;
|
||||||
|
|
||||||
avpkt->pts = frame->pts;
|
s->next_pts = frame->pts + ff_samples_to_time_base(avctx, frame->nb_samples);
|
||||||
avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
|
|
||||||
|
|
||||||
s->next_pts = avpkt->pts + avpkt->duration;
|
|
||||||
|
|
||||||
av_shrink_packet(avpkt, out_bytes);
|
av_shrink_packet(avpkt, out_bytes);
|
||||||
|
|
||||||
@ -1766,5 +1763,5 @@ const FFCodec ff_flac_encoder = {
|
|||||||
AV_SAMPLE_FMT_S32,
|
AV_SAMPLE_FMT_S32,
|
||||||
AV_SAMPLE_FMT_NONE },
|
AV_SAMPLE_FMT_NONE },
|
||||||
.p.priv_class = &flac_encoder_class,
|
.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,
|
||||||
};
|
};
|
||||||
|
@ -158,6 +158,10 @@ int main(void){
|
|||||||
if (codec->capabilities & AV_CODEC_CAP_FRAME_THREADS &&
|
if (codec->capabilities & AV_CODEC_CAP_FRAME_THREADS &&
|
||||||
codec->capabilities & AV_CODEC_CAP_DELAY)
|
codec->capabilities & AV_CODEC_CAP_DELAY)
|
||||||
ERR("Frame-threaded encoder %s claims to have delay\n");
|
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 {
|
} else {
|
||||||
if ((codec->type == AVMEDIA_TYPE_SUBTITLE) != (codec2->cb_type == FF_CODEC_CB_TYPE_DECODE_SUB))
|
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");
|
ERR("Subtitle decoder %s does not implement decode_sub callback\n");
|
||||||
|
Reference in New Issue
Block a user