@@ -290,6 +290,7 @@ enum DecoderFlags {
#if FFMPEG_OPT_TOP
DECODER_FLAG_TOP_FIELD_FIRST = (1 << 3),
#endif
+ DECODER_FLAG_SEND_END_TS = (1 << 4),
};
typedef struct DecoderOpts {
@@ -756,8 +757,11 @@ AVBufferRef *hw_device_for_filter(void);
/**
* @param dec_opts Dictionary filled with decoder options. Its ownership
* is transferred to the decoder.
+ *
+ * @retval ">=0" non-negative scheduler index on success
+ * @retval "<0" an error code on failure
*/
-int dec_open(Decoder **pdec, Scheduler *sch, unsigned sch_idx,
+int dec_open(Decoder **pdec, Scheduler *sch,
AVDictionary **dec_opts, const DecoderOpts *o);
void dec_free(Decoder **pdec);
@@ -847,7 +851,6 @@ const char *opt_match_per_type_str(const SpecifierOptList *sol,
char mediatype);
void *muxer_thread(void *arg);
-void *decoder_thread(void *arg);
void *encoder_thread(void *arg);
#endif /* FFTOOLS_FFMPEG_H */
@@ -645,10 +645,9 @@ fail:
return AVERROR(ENOMEM);
}
-void *decoder_thread(void *arg)
+static void *decoder_thread(void *arg)
{
- InputStream *ist = arg;
- DecoderPriv *dp = dp_from_dec(ist->decoder);
+ DecoderPriv *dp = arg;
DecThreadContext dt;
int ret = 0, input_status = 0;
@@ -692,7 +691,7 @@ void *decoder_thread(void *arg)
break;
/* report last frame duration to the scheduler */
- if (ist->dec->type == AVMEDIA_TYPE_AUDIO) {
+ if (dp->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
dt.pkt->pts = dp->last_frame_pts + dp->last_frame_duration_est;
dt.pkt->time_base = dp->last_frame_tb;
}
@@ -940,7 +939,7 @@ static const AVClass dec_class = {
.item_name = dec_item_name,
};
-int dec_open(Decoder **pdec, Scheduler *sch, unsigned sch_idx,
+int dec_open(Decoder **pdec, Scheduler *sch,
AVDictionary **dec_opts, const DecoderOpts *o)
{
DecoderPriv *dp;
@@ -953,8 +952,11 @@ int dec_open(Decoder **pdec, Scheduler *sch, unsigned sch_idx,
if (ret < 0)
return ret;
+ ret = sch_add_dec(sch, decoder_thread, dp, o->flags & DECODER_FLAG_SEND_END_TS);
+ if (ret < 0)
+ return ret;
dp->sch = sch;
- dp->sch_idx = sch_idx;
+ dp->sch_idx = ret;
dp->flags = o->flags;
dp->dec.class = &dec_class;
@@ -1036,7 +1038,7 @@ int dec_open(Decoder **pdec, Scheduler *sch, unsigned sch_idx,
*pdec = &dp->dec;
- return 0;
+ return dp->sch_idx;
fail:
dec_free((Decoder**)dp);
return ret;
@@ -895,18 +895,9 @@ static int ist_use(InputStream *ist, int decoding_needed)
if (decoding_needed && ds->sch_idx_dec < 0) {
int is_audio = ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO;
- ret = sch_add_dec(d->sch, decoder_thread, ist, d->loop && is_audio);
- if (ret < 0)
- return ret;
- ds->sch_idx_dec = ret;
-
- ret = sch_connect(d->sch, SCH_DSTREAM(d->f.index, ds->sch_idx_stream),
- SCH_DEC(ds->sch_idx_dec));
- if (ret < 0)
- return ret;
-
ds->dec_opts.flags = (!!ist->fix_sub_duration * DECODER_FLAG_FIX_SUB_DURATION) |
- (!!(d->f.ctx->iformat->flags & AVFMT_NOTIMESTAMPS) * DECODER_FLAG_TS_UNRELIABLE)
+ (!!(d->f.ctx->iformat->flags & AVFMT_NOTIMESTAMPS) * DECODER_FLAG_TS_UNRELIABLE) |
+ (!!(d->loop && is_audio) * DECODER_FLAG_SEND_END_TS)
#if FFMPEG_OPT_TOP
| ((ist->top_field_first >= 0) * DECODER_FLAG_TOP_FIELD_FIRST)
#endif
@@ -935,10 +926,16 @@ static int ist_use(InputStream *ist, int decoding_needed)
ds->dec_opts.log_parent = ist;
- ret = dec_open(&ist->decoder, d->sch, ds->sch_idx_dec,
+ ret = dec_open(&ist->decoder, d->sch,
&ist->decoder_opts, &ds->dec_opts);
if (ret < 0)
return ret;
+ ds->sch_idx_dec = ret;
+
+ ret = sch_connect(d->sch, SCH_DSTREAM(d->f.index, ds->sch_idx_stream),
+ SCH_DEC(ds->sch_idx_dec));
+ if (ret < 0)
+ return ret;
d->have_audio_dec |= is_audio;
}