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

Submitted by sebechlebskyjan@gmail.com on Aug. 2, 2016, 1:24 p.m.

Details

Message ID 1470144262-13167-10-git-send-email-sebechlebskyjan@gmail.com
State New
Headers show

Commit Message

sebechlebskyjan@gmail.com Aug. 2, 2016, 1:24 p.m.
From: Jan Sebechlebsky <sebechlebskyjan@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@gmail.com>
---
 libavformat/mux.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

Comments

Michael Niedermayer Aug. 31, 2016, 11:44 p.m.
On Tue, Aug 02, 2016 at 03:24:20PM +0200, sebechlebskyjan@gmail.com wrote:
> From: Jan Sebechlebsky <sebechlebskyjan@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@gmail.com>
> ---
>  libavformat/mux.c | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)

isnt it simpler instead of all the safe and restore to simply skip
compute_muxer_pkt_fields() on (a) subsequent call(s)?
or does that not work ?

iam also thinking that it would be more robust if one considers future
changes that would require more things to be safed and restored

but if thats messier and not simple then this patch
LGTM

thx

[...]

Patch hide | download patch | download mbox

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)