return 0;
}
-static int ifilter_send_eof(InputFilter *ifilter)
+static int ifilter_send_eof(InputFilter *ifilter, int64_t pts)
{
int i, j, ret;
ifilter->eof = 1;
if (ifilter->filter) {
- ret = av_buffersrc_add_frame_flags(ifilter->filter, NULL, AV_BUFFERSRC_FLAG_PUSH);
+ ret = av_buffersrc_close(ifilter->filter, pts, AV_BUFFERSRC_FLAG_PUSH);
if (ret < 0)
return ret;
} else {
return err < 0 ? err : ret;
}
-static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int eof,
+static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_t *duration_pts, int eof,
int *decode_failed)
{
AVFrame *decoded_frame;
ist->hwaccel_retrieved_pix_fmt = decoded_frame->format;
best_effort_timestamp= decoded_frame->best_effort_timestamp;
+ *duration_pts = decoded_frame->pkt_duration;
if (ist->framerate.num)
best_effort_timestamp = ist->cfr_next_pts++;
static int send_filter_eof(InputStream *ist)
{
int i, ret;
+ /* TODO keep pts also in stream time base to avoid converting back */
+ int64_t pts = av_rescale_q_rnd(ist->pts, AV_TIME_BASE_Q, ist->st->time_base,
+ AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
+
for (i = 0; i < ist->nb_filters; i++) {
- ret = ifilter_send_eof(ist->filters[i]);
+ ret = ifilter_send_eof(ist->filters[i], pts);
if (ret < 0)
return ret;
}
// while we have more to decode or while the decoder did output something on EOF
while (ist->decoding_needed) {
- int64_t duration = 0;
+ int64_t duration_dts = 0;
+ int64_t duration_pts = 0;
int got_output = 0;
int decode_failed = 0;
&decode_failed);
break;
case AVMEDIA_TYPE_VIDEO:
- ret = decode_video (ist, repeating ? NULL : &avpkt, &got_output, !pkt,
+ ret = decode_video (ist, repeating ? NULL : &avpkt, &got_output, &duration_pts, !pkt,
&decode_failed);
if (!repeating || !pkt || got_output) {
if (pkt && pkt->duration) {
- duration = av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);
+ duration_dts = av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);
} else if(ist->dec_ctx->framerate.num != 0 && ist->dec_ctx->framerate.den != 0) {
int ticks= av_stream_get_parser(ist->st) ? av_stream_get_parser(ist->st)->repeat_pict+1 : ist->dec_ctx->ticks_per_frame;
- duration = ((int64_t)AV_TIME_BASE *
+ duration_dts = ((int64_t)AV_TIME_BASE *
ist->dec_ctx->framerate.den * ticks) /
ist->dec_ctx->framerate.num / ist->dec_ctx->ticks_per_frame;
}
- if(ist->dts != AV_NOPTS_VALUE && duration) {
- ist->next_dts += duration;
+ if(ist->dts != AV_NOPTS_VALUE && duration_dts) {
+ ist->next_dts += duration_dts;
}else
ist->next_dts = AV_NOPTS_VALUE;
}
if (got_output)
- ist->next_pts += duration; //FIXME the duration is not correct in some cases
+ ist->next_pts += av_rescale_q(duration_pts, ist->st->time_base, AV_TIME_BASE_Q);
break;
case AVMEDIA_TYPE_SUBTITLE:
if (repeating)