@@ -3412,12 +3412,6 @@ static int need_output(void)
if (ost->finished || of_finished(of))
continue;
- if (ost->frame_number >= ost->max_frames) {
- int j;
- for (j = 0; j < of->ctx->nb_streams; j++)
- close_output_stream(output_streams[of->ost_index + j]);
- continue;
- }
return 1;
}
@@ -273,19 +273,11 @@ void of_submit_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int eof)
if (!eof) {
/*
- * Audio encoders may split the packets -- #frames in != #packets out.
- * But there is no reordering, so we can limit the number of output packets
- * by simply dropping them here.
* Counting encoded video frames needs to be done separately because of
* reordering, see do_video_out().
*/
- if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed)) {
- if (ost->frame_number >= ost->max_frames) {
- av_packet_unref(pkt);
- return;
- }
+ if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed))
ost->frame_number++;
- }
}
if (ost->sq_idx_mux >= 0) {
@@ -2304,6 +2304,7 @@ static int init_complex_filters(void)
static int setup_sync_queues(OutputFile *of, AVFormatContext *oc)
{
int nb_av_enc = 0, nb_interleaved = 0;
+ int limit_frames = 0, limit_frames_av_enc = 0;
#define IS_AV_ENC(ost, type) \
(ost->encoding_needed && (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO))
@@ -2318,14 +2319,19 @@ static int setup_sync_queues(OutputFile *of, AVFormatContext *oc)
nb_interleaved += IS_INTERLEAVED(type);
nb_av_enc += IS_AV_ENC(ost, type);
+
+ limit_frames |= ost->max_frames < INT64_MAX;
+ limit_frames_av_enc |= (ost->max_frames < INT64_MAX) && IS_AV_ENC(ost, type);
}
- if (!(nb_interleaved > 1 && of->shortest))
+ if (!((nb_interleaved > 1 && of->shortest) ||
+ (nb_interleaved > 0 && limit_frames)))
return 0;
- /* if we have more than one encoded audio/video streams, then we
+ /* if we have more than one encoded audio/video streams, or at least
+ * one encoded audio/video stream is frame-limited, then we
* synchronize them before encoding */
- if (nb_av_enc > 1) {
+ if ((of->shortest && nb_av_enc > 1) || limit_frames_av_enc) {
of->sq_encode = sq_alloc(SYNC_QUEUE_FRAMES);
if (!of->sq_encode)
return AVERROR(ENOMEM);
@@ -2344,6 +2350,9 @@ static int setup_sync_queues(OutputFile *of, AVFormatContext *oc)
ost->sq_frame = av_frame_alloc();
if (!ost->sq_frame)
return AVERROR(ENOMEM);
+
+ if (ost->max_frames != INT64_MAX)
+ sq_limit_frames(of->sq_encode, ost->sq_idx_encode, ost->max_frames);
}
}
@@ -2364,6 +2373,9 @@ static int setup_sync_queues(OutputFile *of, AVFormatContext *oc)
ost->sq_idx_mux = sq_add_stream(of->sq_mux);
if (ost->sq_idx_mux < 0)
return ost->sq_idx_mux;
+
+ if (ost->max_frames != INT64_MAX)
+ sq_limit_frames(of->sq_mux, ost->sq_idx_mux, ost->max_frames);
}
}
@@ -32,6 +32,9 @@ typedef struct SyncQueueStream {
AVRational tb;
int64_t head_ts;
int finished;
+
+ uint64_t frames_sent;
+ uint64_t frames_max;
} SyncQueueStream;
struct SyncQueue {
@@ -205,6 +208,9 @@ int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame)
}
}
+ st->frames_sent++;
+ if (st->frames_sent >= st->frames_max)
+ finish_stream(sq, stream_idx);
return 0;
}
@@ -297,6 +303,7 @@ int sq_add_stream(SyncQueue *sq)
return AVERROR(ENOMEM);
st->head_ts = AV_NOPTS_VALUE;
+ st->frames_max = UINT64_MAX;
return sq->nb_streams++;
}
@@ -307,6 +314,12 @@ void sq_set_tb(SyncQueue *sq, unsigned int stream_idx, AVRational tb)
sq->streams[stream_idx].tb = tb;
}
+void sq_limit_frames(SyncQueue *sq, unsigned int stream_idx, uint64_t frames)
+{
+ av_assert0(stream_idx < sq->nb_streams);
+ sq->streams[stream_idx].frames_max = frames;
+}
+
SyncQueue *sq_alloc(enum SyncQueueType type)
{
SyncQueue *sq = av_mallocz(sizeof(*sq));
@@ -56,6 +56,13 @@ int sq_add_stream(SyncQueue *sq);
*/
void sq_set_tb(SyncQueue *sq, unsigned int stream_idx, AVRational tb);
+/**
+ * Limit the number of output frames for stream with index stream_idx
+ * to max_frames.
+ */
+void sq_limit_frames(SyncQueue *sq, unsigned int stream_idx,
+ uint64_t max_frames);
+
/**
* Submit a frame for the stream with index stream_idx.
*
@@ -1,8 +1,8 @@
-56ff5763fd81ad3bc02c22402cd685e2 *tests/data/fate/matroska-flac-extradata-update.matroska
-2008 tests/data/fate/matroska-flac-extradata-update.matroska
-#extradata 0: 34, 0x7acb09e7
-#extradata 1: 34, 0x7acb09e7
-#extradata 2: 34, 0x443402dd
+8ec02dffd603f44e08b2ae3b81a0d5a0 *tests/data/fate/matroska-flac-extradata-update.matroska
+1816 tests/data/fate/matroska-flac-extradata-update.matroska
+#extradata 0: 34, 0x93650c81
+#extradata 1: 34, 0x93650c81
+#extradata 2: 34, 0x93650c81
#tb 0: 1/1000
#media_type 0: audio
#codec_id 0: flac
@@ -42,9 +42,3 @@
0, 672, 672, 96, 26, 0x50dd042e
1, 672, 672, 96, 26, 0x50dd042e
2, 672, 672, 96, 26, 0x50dd042e
-0, 768, 768, 96, 26, 0x53de0499
-1, 768, 768, 96, 26, 0x53de0499
-0, 864, 864, 96, 26, 0x53df04b4
-1, 864, 864, 96, 26, 0x53df04b4
-0, 960, 960, 42, 26, 0x5740044b
-1, 960, 960, 42, 26, 0x5740044b
@@ -42,6 +42,3 @@
1, 383, 383, 21, 325, 0xcd7a9fd6
1, 404, 404, 22, 359, 0x6edeb91c
1, 426, 426, 21, 333, 0xb8999fb7
-1, 447, 447, 21, 317, 0xf2589e1a
-1, 468, 468, 21, 319, 0x82ed9572
-1, 489, 489, 22, 473, 0xea54e696