[FFmpeg-devel] [PATCH 09/11] avformat/mux: Restore stream ts in av_write_packet on EAGAIN

sebechlebskyjan at gmail.com sebechlebskyjan at gmail.com
Tue Aug 2 16:24:20 EEST 2016


From: Jan Sebechlebsky <sebechlebskyjan at gmail.com>

compute_muxer_pkt_fields() stores the last seen timestamps in stream
and produces error if the same timestamp is presented again.
This is a problem if muxer works in non-blocking mode and calls
av_write_packet repeatedly with the same packet.
This patch saves stream fields affected by compute_muxer_pkt_fields
and restores them in case AVERROR(EAGAIN) is returned from
write_packet, and muxer has AVFMT_FLAG_NONBLOCK flag set.

Signed-off-by: Jan Sebechlebsky <sebechlebskyjan at gmail.com>
---
 libavformat/mux.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/libavformat/mux.c b/libavformat/mux.c
index ef4720a..fdf3fd1 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -880,6 +880,9 @@ static int do_packet_auto_bsf(AVFormatContext *s, AVPacket *pkt) {
 int av_write_frame(AVFormatContext *s, AVPacket *pkt)
 {
     int ret;
+#if FF_API_COMPUTE_PKT_FIELDS2 && FF_API_LAVF_AVCTX
+    int64_t st_cur_dts_backup, st_priv_pts_val_backup;
+#endif
 
     ret = prepare_input_packet(s, pkt);
     if (ret < 0)
@@ -907,6 +910,9 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt)
         return ret;
 
 #if FF_API_COMPUTE_PKT_FIELDS2 && FF_API_LAVF_AVCTX
+    st_cur_dts_backup = s->streams[pkt->stream_index]->cur_dts;
+    st_priv_pts_val_backup = s->streams[pkt->stream_index]->priv_pts->val;
+
     ret = compute_muxer_pkt_fields(s, s->streams[pkt->stream_index], pkt);
 
     if (ret < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
@@ -914,7 +920,13 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt)
 #endif
 
     ret = write_packet(s, pkt);
-    if (ret >= 0 && s->pb && s->pb->error < 0)
+    if (s->flags & AVFMT_FLAG_NONBLOCK && ret == AVERROR(EAGAIN)) {
+#if FF_API_COMPUTE_PKT_FIELDS2 && FF_API_LAVF_AVCTX
+        s->streams[pkt->stream_index]->cur_dts = st_cur_dts_backup;
+        s->streams[pkt->stream_index]->priv_pts->val = st_priv_pts_val_backup;
+#endif
+        return ret;
+    } else if (ret >= 0 && s->pb && s->pb->error < 0)
         ret = s->pb->error;
 
     if (ret >= 0)
-- 
1.9.1



More information about the ffmpeg-devel mailing list